Skip to content

Commit 98420cc

Browse files
authored
allow reuse of structure discounts (openfrontio#1513)
## Description: When someone loses their structures they get their bonus back. Also keep the structures built, it's nice to still get the bonus after capturing someone's city. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I have read and accepted the CLA aggreement (only required once). ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
1 parent 0489c63 commit 98420cc

2 files changed

Lines changed: 37 additions & 72 deletions

File tree

src/core/configuration/DefaultConfig.ts

Lines changed: 36 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -375,15 +375,9 @@ export class DefaultConfig implements Config {
375375
};
376376
case UnitType.Warship:
377377
return {
378-
cost: (p: Player) =>
379-
p.type() === PlayerType.Human && this.infiniteGold()
380-
? 0n
381-
: BigInt(
382-
Math.min(
383-
1_000_000,
384-
(p.unitsOwned(UnitType.Warship) + 1) * 250_000,
385-
),
386-
),
378+
cost: this.costWrapper(UnitType.Warship, (numUnits: number) =>
379+
Math.min(1_000_000, (numUnits + 1) * 250_000),
380+
),
387381
territoryBound: false,
388382
maxHealth: 1000,
389383
};
@@ -400,42 +394,27 @@ export class DefaultConfig implements Config {
400394
};
401395
case UnitType.Port:
402396
return {
403-
cost: (p: Player) =>
404-
p.type() === PlayerType.Human && this.infiniteGold()
405-
? 0n
406-
: BigInt(
407-
Math.min(
408-
1_000_000,
409-
Math.pow(2, p.unitsConstructed(UnitType.Port)) * 125_000,
410-
),
411-
),
397+
cost: this.costWrapper(UnitType.Port, (numUnits: number) =>
398+
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
399+
),
412400
territoryBound: true,
413401
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
414402
upgradable: true,
415403
canBuildTrainStation: true,
416404
};
417405
case UnitType.AtomBomb:
418406
return {
419-
cost: (p: Player) =>
420-
p.type() === PlayerType.Human && this.infiniteGold()
421-
? 0n
422-
: 750_000n,
407+
cost: this.costWrapper(UnitType.AtomBomb, () => 750_000),
423408
territoryBound: false,
424409
};
425410
case UnitType.HydrogenBomb:
426411
return {
427-
cost: (p: Player) =>
428-
p.type() === PlayerType.Human && this.infiniteGold()
429-
? 0n
430-
: 5_000_000n,
412+
cost: this.costWrapper(UnitType.HydrogenBomb, () => 5_000_000),
431413
territoryBound: false,
432414
};
433415
case UnitType.MIRV:
434416
return {
435-
cost: (p: Player) =>
436-
p.type() === PlayerType.Human && this.infiniteGold()
437-
? 0n
438-
: 35_000_000n,
417+
cost: this.costWrapper(UnitType.MIRV, () => 35_000_000),
439418
territoryBound: false,
440419
};
441420
case UnitType.MIRVWarhead:
@@ -450,70 +429,43 @@ export class DefaultConfig implements Config {
450429
};
451430
case UnitType.MissileSilo:
452431
return {
453-
cost: (p: Player) =>
454-
p.type() === PlayerType.Human && this.infiniteGold()
455-
? 0n
456-
: 1_000_000n,
432+
cost: this.costWrapper(UnitType.MissileSilo, () => 1_000_000),
457433
territoryBound: true,
458434
constructionDuration: this.instantBuild() ? 0 : 10 * 10,
459435
upgradable: true,
460436
};
461437
case UnitType.DefensePost:
462438
return {
463-
cost: (p: Player) =>
464-
p.type() === PlayerType.Human && this.infiniteGold()
465-
? 0n
466-
: BigInt(
467-
Math.min(
468-
250_000,
469-
(p.unitsConstructed(UnitType.DefensePost) + 1) * 50_000,
470-
),
471-
),
439+
cost: this.costWrapper(UnitType.DefensePost, (numUnits: number) =>
440+
Math.min(250_000, (numUnits + 1) * 50_000),
441+
),
472442
territoryBound: true,
473443
constructionDuration: this.instantBuild() ? 0 : 5 * 10,
474444
};
475445
case UnitType.SAMLauncher:
476446
return {
477-
cost: (p: Player) =>
478-
p.type() === PlayerType.Human && this.infiniteGold()
479-
? 0n
480-
: BigInt(
481-
Math.min(
482-
3_000_000,
483-
(p.unitsConstructed(UnitType.SAMLauncher) + 1) * 1_500_000,
484-
),
485-
),
447+
cost: this.costWrapper(UnitType.SAMLauncher, (numUnits: number) =>
448+
Math.min(3_000_000, (numUnits + 1) * 1_500_000),
449+
),
486450
territoryBound: true,
487451
constructionDuration: this.instantBuild() ? 0 : 30 * 10,
488452
upgradable: true,
489453
};
490454
case UnitType.City:
491455
return {
492-
cost: (p: Player) =>
493-
p.type() === PlayerType.Human && this.infiniteGold()
494-
? 0n
495-
: BigInt(
496-
Math.min(
497-
1_000_000,
498-
Math.pow(2, p.unitsConstructed(UnitType.City)) * 125_000,
499-
),
500-
),
456+
cost: this.costWrapper(UnitType.City, (numUnits: number) =>
457+
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
458+
),
501459
territoryBound: true,
502460
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
503461
upgradable: true,
504462
canBuildTrainStation: true,
505463
};
506464
case UnitType.Factory:
507465
return {
508-
cost: (p: Player) =>
509-
p.type() === PlayerType.Human && this.infiniteGold()
510-
? 0n
511-
: BigInt(
512-
Math.min(
513-
1_000_000,
514-
Math.pow(2, p.unitsConstructed(UnitType.Factory)) * 125_000,
515-
),
516-
),
466+
cost: this.costWrapper(UnitType.Factory, (numUnits: number) =>
467+
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
468+
),
517469
territoryBound: true,
518470
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
519471
canBuildTrainStation: true,
@@ -535,6 +487,20 @@ export class DefaultConfig implements Config {
535487
assertNever(type);
536488
}
537489
}
490+
491+
private costWrapper(
492+
type: UnitType,
493+
costFn: (units: number) => number,
494+
): (p: Player) => bigint {
495+
return (p: Player) => {
496+
if (p.type() === PlayerType.Human && this.infiniteGold()) {
497+
return 0n;
498+
}
499+
const numUnits = Math.min(p.unitsOwned(type), p.unitsConstructed(type));
500+
return BigInt(costFn(numUnits));
501+
};
502+
}
503+
538504
defaultDonationAmount(sender: Player): number {
539505
return Math.floor(sender.troops() / 3);
540506
}

src/core/game/Game.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
PlayerUpdate,
88
UnitUpdate,
99
} from "./GameUpdates";
10-
import { PlayerView } from "./GameView";
1110
import { RailNetwork } from "./RailNetwork";
1211
import { Stats } from "./Stats";
1312

@@ -131,7 +130,7 @@ export enum GameMode {
131130
}
132131

133132
export interface UnitInfo {
134-
cost: (player: Player | PlayerView) => Gold;
133+
cost: (player: Player) => Gold;
135134
// Determines if its owner changes when its tile is conquered.
136135
territoryBound: boolean;
137136
maxHealth?: number;

0 commit comments

Comments
 (0)