mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 14:04:36 +00:00
allow reuse of structure discounts (#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
This commit is contained in:
@@ -375,15 +375,9 @@ export class DefaultConfig implements Config {
|
||||
};
|
||||
case UnitType.Warship:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
1_000_000,
|
||||
(p.unitsOwned(UnitType.Warship) + 1) * 250_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.Warship, (numUnits: number) =>
|
||||
Math.min(1_000_000, (numUnits + 1) * 250_000),
|
||||
),
|
||||
territoryBound: false,
|
||||
maxHealth: 1000,
|
||||
};
|
||||
@@ -400,15 +394,9 @@ export class DefaultConfig implements Config {
|
||||
};
|
||||
case UnitType.Port:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
1_000_000,
|
||||
Math.pow(2, p.unitsConstructed(UnitType.Port)) * 125_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.Port, (numUnits: number) =>
|
||||
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
@@ -416,26 +404,17 @@ export class DefaultConfig implements Config {
|
||||
};
|
||||
case UnitType.AtomBomb:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: 750_000n,
|
||||
cost: this.costWrapper(UnitType.AtomBomb, () => 750_000),
|
||||
territoryBound: false,
|
||||
};
|
||||
case UnitType.HydrogenBomb:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: 5_000_000n,
|
||||
cost: this.costWrapper(UnitType.HydrogenBomb, () => 5_000_000),
|
||||
territoryBound: false,
|
||||
};
|
||||
case UnitType.MIRV:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: 35_000_000n,
|
||||
cost: this.costWrapper(UnitType.MIRV, () => 35_000_000),
|
||||
territoryBound: false,
|
||||
};
|
||||
case UnitType.MIRVWarhead:
|
||||
@@ -450,54 +429,33 @@ export class DefaultConfig implements Config {
|
||||
};
|
||||
case UnitType.MissileSilo:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: 1_000_000n,
|
||||
cost: this.costWrapper(UnitType.MissileSilo, () => 1_000_000),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 10 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
case UnitType.DefensePost:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
250_000,
|
||||
(p.unitsConstructed(UnitType.DefensePost) + 1) * 50_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.DefensePost, (numUnits: number) =>
|
||||
Math.min(250_000, (numUnits + 1) * 50_000),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 5 * 10,
|
||||
};
|
||||
case UnitType.SAMLauncher:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
3_000_000,
|
||||
(p.unitsConstructed(UnitType.SAMLauncher) + 1) * 1_500_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.SAMLauncher, (numUnits: number) =>
|
||||
Math.min(3_000_000, (numUnits + 1) * 1_500_000),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 30 * 10,
|
||||
upgradable: true,
|
||||
};
|
||||
case UnitType.City:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
1_000_000,
|
||||
Math.pow(2, p.unitsConstructed(UnitType.City)) * 125_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.City, (numUnits: number) =>
|
||||
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
@@ -505,15 +463,9 @@ export class DefaultConfig implements Config {
|
||||
};
|
||||
case UnitType.Factory:
|
||||
return {
|
||||
cost: (p: Player) =>
|
||||
p.type() === PlayerType.Human && this.infiniteGold()
|
||||
? 0n
|
||||
: BigInt(
|
||||
Math.min(
|
||||
1_000_000,
|
||||
Math.pow(2, p.unitsConstructed(UnitType.Factory)) * 125_000,
|
||||
),
|
||||
),
|
||||
cost: this.costWrapper(UnitType.Factory, (numUnits: number) =>
|
||||
Math.min(1_000_000, Math.pow(2, numUnits) * 125_000),
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
canBuildTrainStation: true,
|
||||
@@ -535,6 +487,20 @@ export class DefaultConfig implements Config {
|
||||
assertNever(type);
|
||||
}
|
||||
}
|
||||
|
||||
private costWrapper(
|
||||
type: UnitType,
|
||||
costFn: (units: number) => number,
|
||||
): (p: Player) => bigint {
|
||||
return (p: Player) => {
|
||||
if (p.type() === PlayerType.Human && this.infiniteGold()) {
|
||||
return 0n;
|
||||
}
|
||||
const numUnits = Math.min(p.unitsOwned(type), p.unitsConstructed(type));
|
||||
return BigInt(costFn(numUnits));
|
||||
};
|
||||
}
|
||||
|
||||
defaultDonationAmount(sender: Player): number {
|
||||
return Math.floor(sender.troops() / 3);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
PlayerUpdate,
|
||||
UnitUpdate,
|
||||
} from "./GameUpdates";
|
||||
import { PlayerView } from "./GameView";
|
||||
import { RailNetwork } from "./RailNetwork";
|
||||
import { Stats } from "./Stats";
|
||||
|
||||
@@ -131,7 +130,7 @@ export enum GameMode {
|
||||
}
|
||||
|
||||
export interface UnitInfo {
|
||||
cost: (player: Player | PlayerView) => Gold;
|
||||
cost: (player: Player) => Gold;
|
||||
// Determines if its owner changes when its tile is conquered.
|
||||
territoryBound: boolean;
|
||||
maxHealth?: number;
|
||||
|
||||
Reference in New Issue
Block a user