@civ-clone/base-unit-fuel 0.0.0-stage → 0.1.0
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 +4 -0
- package/.github/workflows/build-on-push.yml +39 -0
- package/.prettierrc +4 -0
- package/LICENSE +21 -0
- package/README.md +57 -2
- package/lib/Aloft.d.ts +14 -0
- package/lib/Aloft.js +25 -0
- package/lib/Aloft.js.map +1 -0
- package/lib/Aloft.ts +29 -0
- package/lib/Fuel.d.ts +8 -0
- package/lib/Fuel.js +14 -0
- package/lib/Fuel.js.map +1 -0
- package/lib/Fuel.ts +10 -0
- package/lib/Rules.d.ts +10 -0
- package/lib/Rules.js +16 -0
- package/lib/Rules.js.map +1 -0
- package/lib/Rules.ts +12 -0
- package/lib/fuelRules.d.ts +95 -0
- package/lib/fuelRules.js +133 -0
- package/lib/fuelRules.js.map +1 -0
- package/lib/fuelRules.ts +277 -0
- package/lib/reach.d.ts +41 -0
- package/lib/reach.js +47 -0
- package/lib/reach.js.map +1 -0
- package/lib/reach.ts +97 -0
- package/lib/refuel.d.ts +38 -0
- package/lib/refuel.js +35 -0
- package/lib/refuel.js.map +1 -0
- package/lib/refuel.ts +98 -0
- package/package.json +43 -4
- package/tests/fuel.test.ts +460 -0
- package/tests/save.test.ts +54 -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,58 @@
|
|
|
1
|
-
#
|
|
1
|
+
# base-unit-fuel
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Fuel for units that must return to base: a range, the turns a unit has ended out, where it refuels, and running out. A
|
|
4
|
+
library: nothing registers on import, and a game that registers none of it has no fuel.
|
|
5
|
+
|
|
6
|
+
## API
|
|
7
|
+
|
|
8
|
+
Deep-import the modules; there is no index.
|
|
9
|
+
|
|
10
|
+
- `lib/Fuel`: `Fuel`, the unit yield that gives a unit's range: how many of its player's turns it can end away from a
|
|
11
|
+
refuelling point, counting the one it set out in (1: it must refuel every turn; 2: it can stay out one turn). 0, as
|
|
12
|
+
with no `Yield` rule for it, needs no fuel.
|
|
13
|
+
- `lib/fuelRules`: `fuelRules({ ruleRegistry, unitImprovementRegistry, unitRegistry }, { prefix?, range?, countOn?,
|
|
14
|
+
countsAsMove?, isAttack? })`:
|
|
15
|
+
- a rule that counts turns out, as `countOn` says (see below);
|
|
16
|
+
- an `OutOfFuel` rule that destroys the unit. A game adds its own `OutOfFuel` rules for anything else (a notice).
|
|
17
|
+
- `range(unit)` is the unit's `Fuel` yield by default (`fuelRange`); a game can read its own table instead.
|
|
18
|
+
- helpers: `refuels(ruleRegistry, unit, tile?)`, `turnsAloft(unitImprovementRegistry, unit)`, `aloftOf(...)`,
|
|
19
|
+
`checkFuel(...)` and `checkFuelAfterMove(...)`.
|
|
20
|
+
- Rule ids `<prefix>:player/turn-end/fuel` (or `<prefix>:unit/moved/fuel`) and `<prefix>:unit/out-of-fuel/destroy`.
|
|
21
|
+
- `lib/Rules`: `Refuel(unit, tile) → boolean` (a unit refuels on a square if any rule's criteria match and its effect
|
|
22
|
+
answers `true`) and `OutOfFuel(unit)`.
|
|
23
|
+
- `lib/refuel`, `Refuel` rules a game registers, each with an optional `applies(unit)` filter and id:
|
|
24
|
+
`refuelInOwnCity(cityRegistry)`, `refuelOnTileImprovement(Improvement, tileImprovementRegistry)`,
|
|
25
|
+
`refuelInStackWith(isBase(base, unit), unitRegistry)` (another of the player's units on the square, such as one that
|
|
26
|
+
carries it) and `refuelAboard(transportRegistry)`.
|
|
27
|
+
- `lib/reach`, for computer players:
|
|
28
|
+
- `fuelState(unitImprovementRegistry, unit, range?)`: `{ range, turnsAloft, turnsLeft, reach }`, `turnsLeft` counting
|
|
29
|
+
this turn, and `reach` the moves before the end of the last of them (moves left, then full movement each turn);
|
|
30
|
+
`null` for a unit with no range.
|
|
31
|
+
- `refuelInReach(ruleRegistry, unitImprovementRegistry, unit, { range?, distance?, candidates? })`: the nearest
|
|
32
|
+
square within reach where the unit refuels, or `null`.
|
|
33
|
+
|
|
34
|
+
## When fuel is counted
|
|
35
|
+
|
|
36
|
+
`countOn` chooses:
|
|
37
|
+
|
|
38
|
+
- `'turn-end'` (the default): a `TurnEnd` rule. At the end of each of the player's turns, a unit with a range that
|
|
39
|
+
refuels where it is loses its count; any other has ended one more turn out, and runs out of fuel (`OutOfFuel`) when
|
|
40
|
+
that reaches its range. It doesn't matter whether the unit spent its moves. This is how civ1-unit's own fuel rule
|
|
41
|
+
counts, so that rule can move onto this package later with the same behaviour.
|
|
42
|
+
- `'out-of-moves'`: a `Moved` rule, as OpenCiv2 (github.com/richardpenman/civ2, read at 49f26ec,
|
|
43
|
+
`unit_move_dir_air_fuel`) counts. After a move (`countsAsMove`, by default an action to another square), a unit that
|
|
44
|
+
refuels where it is has landed: it loses its count and its remaining moves. The exception is a unit with a range of 1
|
|
45
|
+
that attacked (`isAttack`, by default it didn't end up on its target) and still has moves, which hasn't landed. A unit
|
|
46
|
+
anywhere else, left with no moves, has spent one more turn out, and runs out of fuel when that reaches its range. A
|
|
47
|
+
unit that ends its turn with moves unspent isn't counted, as in the original.
|
|
48
|
+
|
|
49
|
+
The places the original refuels (a city, an airbase, a stack with a unit that carries it) are the rules in
|
|
50
|
+
`lib/refuel`.
|
|
51
|
+
|
|
52
|
+
## The count is saved
|
|
53
|
+
|
|
54
|
+
`Aloft` (a `UnitImprovement` holding the count) exists only for a unit that is out, and goes when it refuels, so a
|
|
55
|
+
unit at its base carries and saves nothing extra. A game that saves registers it in its
|
|
56
|
+
`AvailableUnitImprovementRegistry` (`tests/save.test.ts` round-trips it through core-save-game; without that, loading
|
|
57
|
+
fails with "Unknown entity type 'Aloft'"). It is also sent to clients in a unit's `improvements`, so a client should leave it
|
|
58
|
+
out of what it shows (or show the count).
|
package/lib/Aloft.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Unit from '@civ-clone/core-unit/Unit';
|
|
2
|
+
import UnitImprovement from '@civ-clone/core-unit-improvement/UnitImprovement';
|
|
3
|
+
/**
|
|
4
|
+
* How many of its player's turns a fuelled unit has ended away from somewhere it refuels. Only a unit that is out has
|
|
5
|
+
* one, and it goes when the unit refuels, so a unit at its base carries and saves nothing extra. A game that saves
|
|
6
|
+
* needs it in its `AvailableUnitImprovementRegistry`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Aloft extends UnitImprovement {
|
|
9
|
+
private _turns;
|
|
10
|
+
constructor(unit: Unit, turns?: number);
|
|
11
|
+
turns(): number;
|
|
12
|
+
setTurns(turns: number): void;
|
|
13
|
+
}
|
|
14
|
+
export default Aloft;
|
package/lib/Aloft.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Aloft = void 0;
|
|
4
|
+
const UnitImprovement_1 = require("@civ-clone/core-unit-improvement/UnitImprovement");
|
|
5
|
+
/**
|
|
6
|
+
* How many of its player's turns a fuelled unit has ended away from somewhere it refuels. Only a unit that is out has
|
|
7
|
+
* one, and it goes when the unit refuels, so a unit at its base carries and saves nothing extra. A game that saves
|
|
8
|
+
* needs it in its `AvailableUnitImprovementRegistry`.
|
|
9
|
+
*/
|
|
10
|
+
class Aloft extends UnitImprovement_1.default {
|
|
11
|
+
constructor(unit, turns = 1) {
|
|
12
|
+
super(unit);
|
|
13
|
+
this._turns = turns;
|
|
14
|
+
this.addKey('turns');
|
|
15
|
+
}
|
|
16
|
+
turns() {
|
|
17
|
+
return this._turns;
|
|
18
|
+
}
|
|
19
|
+
setTurns(turns) {
|
|
20
|
+
this._turns = turns;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.Aloft = Aloft;
|
|
24
|
+
exports.default = Aloft;
|
|
25
|
+
//# sourceMappingURL=Aloft.js.map
|
package/lib/Aloft.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aloft.js","sourceRoot":"","sources":["Aloft.ts"],"names":[],"mappings":";;;AACA,sFAA+E;AAE/E;;;;GAIG;AACH,MAAa,KAAM,SAAQ,yBAAe;IAGxC,YAAY,IAAU,EAAE,QAAgB,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEZ,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;CACF;AAlBD,sBAkBC;AAED,kBAAe,KAAK,CAAC"}
|
package/lib/Aloft.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Unit from '@civ-clone/core-unit/Unit';
|
|
2
|
+
import UnitImprovement from '@civ-clone/core-unit-improvement/UnitImprovement';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* How many of its player's turns a fuelled unit has ended away from somewhere it refuels. Only a unit that is out has
|
|
6
|
+
* one, and it goes when the unit refuels, so a unit at its base carries and saves nothing extra. A game that saves
|
|
7
|
+
* needs it in its `AvailableUnitImprovementRegistry`.
|
|
8
|
+
*/
|
|
9
|
+
export class Aloft extends UnitImprovement {
|
|
10
|
+
private _turns: number;
|
|
11
|
+
|
|
12
|
+
constructor(unit: Unit, turns: number = 1) {
|
|
13
|
+
super(unit);
|
|
14
|
+
|
|
15
|
+
this._turns = turns;
|
|
16
|
+
|
|
17
|
+
this.addKey('turns');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
turns(): number {
|
|
21
|
+
return this._turns;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setTurns(turns: number): void {
|
|
25
|
+
this._turns = turns;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default Aloft;
|
package/lib/Fuel.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Yield from '@civ-clone/core-yield/Yield';
|
|
2
|
+
/**
|
|
3
|
+
* How many of its player's turns a unit can end away from somewhere it refuels (see `Refuel`), counting the one it set
|
|
4
|
+
* out in: at 1 it must refuel by the end of each turn, at 2 it can stay out for one turn. A unit with none (0, as a
|
|
5
|
+
* game that registers no `Yield` rule for it leaves every unit) needs no fuel.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Fuel extends Yield {}
|
|
8
|
+
export default Fuel;
|
package/lib/Fuel.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Fuel = void 0;
|
|
4
|
+
const Yield_1 = require("@civ-clone/core-yield/Yield");
|
|
5
|
+
/**
|
|
6
|
+
* How many of its player's turns a unit can end away from somewhere it refuels (see `Refuel`), counting the one it set
|
|
7
|
+
* out in: at 1 it must refuel by the end of each turn, at 2 it can stay out for one turn. A unit with none (0, as a
|
|
8
|
+
* game that registers no `Yield` rule for it leaves every unit) needs no fuel.
|
|
9
|
+
*/
|
|
10
|
+
class Fuel extends Yield_1.default {
|
|
11
|
+
}
|
|
12
|
+
exports.Fuel = Fuel;
|
|
13
|
+
exports.default = Fuel;
|
|
14
|
+
//# sourceMappingURL=Fuel.js.map
|
package/lib/Fuel.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Fuel.js","sourceRoot":"","sources":["Fuel.ts"],"names":[],"mappings":";;;AAAA,uDAAgD;AAEhD;;;;GAIG;AACH,MAAa,IAAK,SAAQ,eAAK;CAAG;AAAlC,oBAAkC;AAElC,kBAAe,IAAI,CAAC"}
|
package/lib/Fuel.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Yield from '@civ-clone/core-yield/Yield';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* How many of its player's turns a unit can end away from somewhere it refuels (see `Refuel`), counting the one it set
|
|
5
|
+
* out in: at 1 it must refuel by the end of each turn, at 2 it can stay out for one turn. A unit with none (0, as a
|
|
6
|
+
* game that registers no `Yield` rule for it leaves every unit) needs no fuel.
|
|
7
|
+
*/
|
|
8
|
+
export class Fuel extends Yield {}
|
|
9
|
+
|
|
10
|
+
export default Fuel;
|
package/lib/Rules.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Rule from '@civ-clone/core-rule/Rule';
|
|
2
|
+
import Tile from '@civ-clone/core-world/Tile';
|
|
3
|
+
import Unit from '@civ-clone/core-unit/Unit';
|
|
4
|
+
/**
|
|
5
|
+
* Whether `unit` refuels on `tile`: it does if any rule's criteria match and its effect returns `true`. A game says
|
|
6
|
+
* where with its criteria (see `refuelInOwnCity`, `refuelOnTileImprovement`, `refuelInStackWith`, `refuelAboard`).
|
|
7
|
+
*/
|
|
8
|
+
export declare class Refuel extends Rule<[unit: Unit, tile: Tile], boolean> {}
|
|
9
|
+
/** `unit` ran out of fuel away from anywhere it refuels. `fuelRules` adds one that destroys it. */
|
|
10
|
+
export declare class OutOfFuel extends Rule<[unit: Unit], void> {}
|
package/lib/Rules.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OutOfFuel = exports.Refuel = void 0;
|
|
4
|
+
const Rule_1 = require("@civ-clone/core-rule/Rule");
|
|
5
|
+
/**
|
|
6
|
+
* Whether `unit` refuels on `tile`: it does if any rule's criteria match and its effect returns `true`. A game says
|
|
7
|
+
* where with its criteria (see `refuelInOwnCity`, `refuelOnTileImprovement`, `refuelInStackWith`, `refuelAboard`).
|
|
8
|
+
*/
|
|
9
|
+
class Refuel extends Rule_1.default {
|
|
10
|
+
}
|
|
11
|
+
exports.Refuel = Refuel;
|
|
12
|
+
/** `unit` ran out of fuel away from anywhere it refuels. `fuelRules` adds one that destroys it. */
|
|
13
|
+
class OutOfFuel extends Rule_1.default {
|
|
14
|
+
}
|
|
15
|
+
exports.OutOfFuel = OutOfFuel;
|
|
16
|
+
//# sourceMappingURL=Rules.js.map
|
package/lib/Rules.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Rules.js","sourceRoot":"","sources":["Rules.ts"],"names":[],"mappings":";;;AAAA,oDAA6C;AAI7C;;;GAGG;AACH,MAAa,MAAO,SAAQ,cAAuC;CAAG;AAAtE,wBAAsE;AAEtE,mGAAmG;AACnG,MAAa,SAAU,SAAQ,cAAwB;CAAG;AAA1D,8BAA0D"}
|
package/lib/Rules.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Rule from '@civ-clone/core-rule/Rule';
|
|
2
|
+
import Tile from '@civ-clone/core-world/Tile';
|
|
3
|
+
import Unit from '@civ-clone/core-unit/Unit';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether `unit` refuels on `tile`: it does if any rule's criteria match and its effect returns `true`. A game says
|
|
7
|
+
* where with its criteria (see `refuelInOwnCity`, `refuelOnTileImprovement`, `refuelInStackWith`, `refuelAboard`).
|
|
8
|
+
*/
|
|
9
|
+
export class Refuel extends Rule<[unit: Unit, tile: Tile], boolean> {}
|
|
10
|
+
|
|
11
|
+
/** `unit` ran out of fuel away from anywhere it refuels. `fuelRules` adds one that destroys it. */
|
|
12
|
+
export class OutOfFuel extends Rule<[unit: Unit], void> {}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { OutOfFuel } from './Rules';
|
|
2
|
+
import { RuleRegistry } from '@civ-clone/core-rule/RuleRegistry';
|
|
3
|
+
import { UnitImprovementRegistry } from '@civ-clone/core-unit-improvement/UnitImprovementRegistry';
|
|
4
|
+
import { UnitRegistry } from '@civ-clone/core-unit/UnitRegistry';
|
|
5
|
+
import Action from '@civ-clone/core-unit/Action';
|
|
6
|
+
import Aloft from './Aloft';
|
|
7
|
+
import Moved from '@civ-clone/core-unit/Rules/Moved';
|
|
8
|
+
import Player from '@civ-clone/core-player/Player';
|
|
9
|
+
import Tile from '@civ-clone/core-world/Tile';
|
|
10
|
+
import TurnEnd from '@civ-clone/core-player/Rules/TurnEnd';
|
|
11
|
+
import Unit from '@civ-clone/core-unit/Unit';
|
|
12
|
+
export interface FuelDependencies {
|
|
13
|
+
ruleRegistry?: RuleRegistry;
|
|
14
|
+
unitImprovementRegistry?: UnitImprovementRegistry;
|
|
15
|
+
unitRegistry?: UnitRegistry;
|
|
16
|
+
}
|
|
17
|
+
/** A unit's range: how many turns it can end away from a refuelling point. */
|
|
18
|
+
export type Range = (unit: Unit) => number;
|
|
19
|
+
/**
|
|
20
|
+
* When a unit's turns out are counted:
|
|
21
|
+
*
|
|
22
|
+
* - `'turn-end'`: at the end of each of its player's turns, wherever it is (`checkFuel`);
|
|
23
|
+
* - `'out-of-moves'`: after each move, as the original does (`checkFuelAfterMove`).
|
|
24
|
+
*/
|
|
25
|
+
export type CountOn = 'turn-end' | 'out-of-moves';
|
|
26
|
+
export interface FuelOptions {
|
|
27
|
+
/**
|
|
28
|
+
* The rules' ids are `<prefix>:player/turn-end/fuel` (or `<prefix>:unit/moved/fuel`) and
|
|
29
|
+
* `<prefix>:unit/out-of-fuel/destroy`. Unnamed without.
|
|
30
|
+
*/
|
|
31
|
+
prefix?: string;
|
|
32
|
+
/** A unit's range: its `Fuel` yield by default. */
|
|
33
|
+
range?: Range;
|
|
34
|
+
/** When turns out are counted: `'turn-end'` by default. */
|
|
35
|
+
countOn?: CountOn;
|
|
36
|
+
/** For `'out-of-moves'`, whether a `Moved` action is a move: by default, one to another square (attacks included). */
|
|
37
|
+
countsAsMove?: (unit: Unit, action: Action) => boolean;
|
|
38
|
+
/** For `'out-of-moves'`, whether the action was an attack: by default, the unit didn't end up on its target. */
|
|
39
|
+
isAttack?: (unit: Unit, action: Action) => boolean;
|
|
40
|
+
}
|
|
41
|
+
/** A unit's `Fuel` yield. */
|
|
42
|
+
export declare const fuelRange: Range;
|
|
43
|
+
/** `unit`'s `Aloft` mark, if it has one. */
|
|
44
|
+
export declare const aloftOf: (
|
|
45
|
+
unitImprovementRegistry: UnitImprovementRegistry,
|
|
46
|
+
unit: Unit
|
|
47
|
+
) => Aloft | undefined;
|
|
48
|
+
/** How many turns `unit` has ended away from a refuelling point since it last refuelled. */
|
|
49
|
+
export declare const turnsAloft: (
|
|
50
|
+
unitImprovementRegistry: UnitImprovementRegistry,
|
|
51
|
+
unit: Unit
|
|
52
|
+
) => number;
|
|
53
|
+
/** Whether `unit` refuels on `tile` (see `Refuel`). */
|
|
54
|
+
export declare const refuels: (
|
|
55
|
+
ruleRegistry: RuleRegistry,
|
|
56
|
+
unit: Unit,
|
|
57
|
+
tile?: Tile
|
|
58
|
+
) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* At the end of `player`'s turn, for each of its units with a range (above 0): one that refuels where it is loses its
|
|
61
|
+
* `Aloft` mark; any other has ended one more turn out, and runs out of fuel (`OutOfFuel`) once that reaches its range.
|
|
62
|
+
*/
|
|
63
|
+
export declare const checkFuel: (
|
|
64
|
+
ruleRegistry: RuleRegistry,
|
|
65
|
+
unitImprovementRegistry: UnitImprovementRegistry,
|
|
66
|
+
unitRegistry: UnitRegistry,
|
|
67
|
+
range: Range
|
|
68
|
+
) => (player: Player) => void;
|
|
69
|
+
/**
|
|
70
|
+
* After `unit` moves (OpenCiv2, `unit_move_dir_air_fuel`), for a unit with a range (above 0):
|
|
71
|
+
*
|
|
72
|
+
* - where it refuels, it loses its `Aloft` mark and its remaining moves (it has landed), except that a unit with a
|
|
73
|
+
* range of 1 that attacked and still has moves left hasn't landed;
|
|
74
|
+
* - anywhere else, once it has no moves left, it has spent one more turn out, and runs out of fuel (`OutOfFuel`) when
|
|
75
|
+
* that reaches its range.
|
|
76
|
+
*/
|
|
77
|
+
export declare const checkFuelAfterMove: (
|
|
78
|
+
ruleRegistry: RuleRegistry,
|
|
79
|
+
unitImprovementRegistry: UnitImprovementRegistry,
|
|
80
|
+
range: Range,
|
|
81
|
+
isAttack: (unit: Unit, action: Action) => boolean
|
|
82
|
+
) => (unit: Unit, action: Action) => void;
|
|
83
|
+
/**
|
|
84
|
+
* A ruleset's fuel rules: one that counts the turns each unit with a range spends away from a refuelling point, and an
|
|
85
|
+
* `OutOfFuel` rule that destroys a unit that runs out. A game adds its own `Refuel` rules (see `lib/refuel`), and its
|
|
86
|
+
* own `OutOfFuel` rules for anything else that should happen (a notice, say).
|
|
87
|
+
*
|
|
88
|
+
* With `countOn: 'turn-end'` (the default) the count is a `TurnEnd` rule (`checkFuel`): it doesn't matter whether a
|
|
89
|
+
* unit spent its moves. With `'out-of-moves'` it is a `Moved` rule (`checkFuelAfterMove`), as the original counts it.
|
|
90
|
+
*/
|
|
91
|
+
export declare const fuelRules: (
|
|
92
|
+
{ ruleRegistry, unitImprovementRegistry, unitRegistry }: FuelDependencies,
|
|
93
|
+
{ prefix, range, countOn, countsAsMove, isAttack }?: FuelOptions
|
|
94
|
+
) => (TurnEnd | Moved | OutOfFuel)[];
|
|
95
|
+
export default fuelRules;
|
package/lib/fuelRules.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fuelRules = exports.checkFuelAfterMove = exports.checkFuel = exports.refuels = exports.turnsAloft = exports.aloftOf = exports.fuelRange = void 0;
|
|
4
|
+
const Rules_1 = require("./Rules");
|
|
5
|
+
const RuleRegistry_1 = require("@civ-clone/core-rule/RuleRegistry");
|
|
6
|
+
const UnitImprovementRegistry_1 = require("@civ-clone/core-unit-improvement/UnitImprovementRegistry");
|
|
7
|
+
const UnitRegistry_1 = require("@civ-clone/core-unit/UnitRegistry");
|
|
8
|
+
const Aloft_1 = require("./Aloft");
|
|
9
|
+
const Criterion_1 = require("@civ-clone/core-rule/Criterion");
|
|
10
|
+
const Effect_1 = require("@civ-clone/core-rule/Effect");
|
|
11
|
+
const Fuel_1 = require("./Fuel");
|
|
12
|
+
const Moved_1 = require("@civ-clone/core-unit/Rules/Moved");
|
|
13
|
+
const TurnEnd_1 = require("@civ-clone/core-player/Rules/TurnEnd");
|
|
14
|
+
/** A unit's `Fuel` yield. */
|
|
15
|
+
const fuelRange = (unit) => {
|
|
16
|
+
const [range] = unit.yield(new Fuel_1.default());
|
|
17
|
+
return range.value();
|
|
18
|
+
};
|
|
19
|
+
exports.fuelRange = fuelRange;
|
|
20
|
+
/** `unit`'s `Aloft` mark, if it has one. */
|
|
21
|
+
const aloftOf = (unitImprovementRegistry, unit) => unitImprovementRegistry
|
|
22
|
+
.getByUnit(unit)
|
|
23
|
+
.find((unitImprovement) => unitImprovement instanceof Aloft_1.default);
|
|
24
|
+
exports.aloftOf = aloftOf;
|
|
25
|
+
/** How many turns `unit` has ended away from a refuelling point since it last refuelled. */
|
|
26
|
+
const turnsAloft = (unitImprovementRegistry, unit) => { var _a, _b; return (_b = (_a = (0, exports.aloftOf)(unitImprovementRegistry, unit)) === null || _a === void 0 ? void 0 : _a.turns()) !== null && _b !== void 0 ? _b : 0; };
|
|
27
|
+
exports.turnsAloft = turnsAloft;
|
|
28
|
+
/** Whether `unit` refuels on `tile` (see `Refuel`). */
|
|
29
|
+
const refuels = (ruleRegistry, unit, tile = unit.tile()) => ruleRegistry
|
|
30
|
+
.process(Rules_1.Refuel, unit, tile)
|
|
31
|
+
.some((answer) => answer === true);
|
|
32
|
+
exports.refuels = refuels;
|
|
33
|
+
/**
|
|
34
|
+
* At the end of `player`'s turn, for each of its units with a range (above 0): one that refuels where it is loses its
|
|
35
|
+
* `Aloft` mark; any other has ended one more turn out, and runs out of fuel (`OutOfFuel`) once that reaches its range.
|
|
36
|
+
*/
|
|
37
|
+
const checkFuel = (ruleRegistry, unitImprovementRegistry, unitRegistry, range) => (player) => unitRegistry.getByPlayer(player).forEach((unit) => {
|
|
38
|
+
var _a;
|
|
39
|
+
if (unit.destroyed()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const unitRange = range(unit);
|
|
43
|
+
if (!(unitRange > 0)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const aloft = (0, exports.aloftOf)(unitImprovementRegistry, unit);
|
|
47
|
+
if ((0, exports.refuels)(ruleRegistry, unit)) {
|
|
48
|
+
if (aloft !== undefined) {
|
|
49
|
+
unitImprovementRegistry.unregister(aloft);
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const turns = ((_a = aloft === null || aloft === void 0 ? void 0 : aloft.turns()) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
54
|
+
if (turns < unitRange) {
|
|
55
|
+
if (aloft === undefined) {
|
|
56
|
+
unitImprovementRegistry.register(new Aloft_1.default(unit, turns));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
aloft.setTurns(turns);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (aloft !== undefined) {
|
|
63
|
+
unitImprovementRegistry.unregister(aloft);
|
|
64
|
+
}
|
|
65
|
+
ruleRegistry.process(Rules_1.OutOfFuel, unit);
|
|
66
|
+
});
|
|
67
|
+
exports.checkFuel = checkFuel;
|
|
68
|
+
/**
|
|
69
|
+
* After `unit` moves (OpenCiv2, `unit_move_dir_air_fuel`), for a unit with a range (above 0):
|
|
70
|
+
*
|
|
71
|
+
* - where it refuels, it loses its `Aloft` mark and its remaining moves (it has landed), except that a unit with a
|
|
72
|
+
* range of 1 that attacked and still has moves left hasn't landed;
|
|
73
|
+
* - anywhere else, once it has no moves left, it has spent one more turn out, and runs out of fuel (`OutOfFuel`) when
|
|
74
|
+
* that reaches its range.
|
|
75
|
+
*/
|
|
76
|
+
const checkFuelAfterMove = (ruleRegistry, unitImprovementRegistry, range, isAttack) => (unit, action) => {
|
|
77
|
+
var _a;
|
|
78
|
+
if (unit.destroyed()) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const unitRange = range(unit);
|
|
82
|
+
if (!(unitRange > 0)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const aloft = (0, exports.aloftOf)(unitImprovementRegistry, unit), landed = (0, exports.refuels)(ruleRegistry, unit) &&
|
|
86
|
+
!(unitRange === 1 &&
|
|
87
|
+
unit.moves().value() > 0 &&
|
|
88
|
+
isAttack(unit, action));
|
|
89
|
+
if (landed) {
|
|
90
|
+
if (aloft !== undefined) {
|
|
91
|
+
unitImprovementRegistry.unregister(aloft);
|
|
92
|
+
}
|
|
93
|
+
unit.moves().set(0);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (unit.moves().value() > 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const turns = ((_a = aloft === null || aloft === void 0 ? void 0 : aloft.turns()) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
100
|
+
if (turns < unitRange) {
|
|
101
|
+
if (aloft === undefined) {
|
|
102
|
+
unitImprovementRegistry.register(new Aloft_1.default(unit, turns));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
aloft.setTurns(turns);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (aloft !== undefined) {
|
|
109
|
+
unitImprovementRegistry.unregister(aloft);
|
|
110
|
+
}
|
|
111
|
+
ruleRegistry.process(Rules_1.OutOfFuel, unit);
|
|
112
|
+
};
|
|
113
|
+
exports.checkFuelAfterMove = checkFuelAfterMove;
|
|
114
|
+
/**
|
|
115
|
+
* A ruleset's fuel rules: one that counts the turns each unit with a range spends away from a refuelling point, and an
|
|
116
|
+
* `OutOfFuel` rule that destroys a unit that runs out. A game adds its own `Refuel` rules (see `lib/refuel`), and its
|
|
117
|
+
* own `OutOfFuel` rules for anything else that should happen (a notice, say).
|
|
118
|
+
*
|
|
119
|
+
* With `countOn: 'turn-end'` (the default) the count is a `TurnEnd` rule (`checkFuel`): it doesn't matter whether a
|
|
120
|
+
* unit spent its moves. With `'out-of-moves'` it is a `Moved` rule (`checkFuelAfterMove`), as the original counts it.
|
|
121
|
+
*/
|
|
122
|
+
const fuelRules = ({ ruleRegistry = RuleRegistry_1.instance, unitImprovementRegistry = UnitImprovementRegistry_1.instance, unitRegistry = UnitRegistry_1.instance, }, { prefix, range = exports.fuelRange, countOn = 'turn-end', countsAsMove = (unit, action) => action.from() !== action.to(), isAttack = (unit, action) => unit.tile() !== action.to(), } = {}) => {
|
|
123
|
+
const id = (name) => prefix === undefined ? [] : [`${prefix}:${name}`];
|
|
124
|
+
return [
|
|
125
|
+
countOn === 'out-of-moves'
|
|
126
|
+
? new Moved_1.default(...id('unit/moved/fuel'), new Criterion_1.default(countsAsMove), new Effect_1.default((0, exports.checkFuelAfterMove)(ruleRegistry, unitImprovementRegistry, range, isAttack)))
|
|
127
|
+
: new TurnEnd_1.default(...id('player/turn-end/fuel'), new Effect_1.default((0, exports.checkFuel)(ruleRegistry, unitImprovementRegistry, unitRegistry, range))),
|
|
128
|
+
new Rules_1.OutOfFuel(...id('unit/out-of-fuel/destroy'), new Effect_1.default((unit) => unit.destroy())),
|
|
129
|
+
];
|
|
130
|
+
};
|
|
131
|
+
exports.fuelRules = fuelRules;
|
|
132
|
+
exports.default = exports.fuelRules;
|
|
133
|
+
//# sourceMappingURL=fuelRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuelRules.js","sourceRoot":"","sources":["fuelRules.ts"],"names":[],"mappings":"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"}
|