mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 19:33:05 +00:00
update defaultconfig file
This commit is contained in:
@@ -56,7 +56,11 @@ export abstract class DefaultServerConfig implements ServerConfig {
|
||||
r2SecretKey(): string {
|
||||
return process.env.R2_SECRET_KEY;
|
||||
}
|
||||
abstract r2Bucket(): string;
|
||||
|
||||
r2Bucket(): string {
|
||||
return process.env.R2_BUCKET;
|
||||
}
|
||||
|
||||
adminHeader(): string {
|
||||
return "x-admin-key";
|
||||
}
|
||||
@@ -196,13 +200,13 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
|
||||
cityPopulationIncrease(): number {
|
||||
return 250_000;
|
||||
return 500_000;
|
||||
}
|
||||
|
||||
falloutDefenseModifier(falloutRatio: number): number {
|
||||
// falloutRatio is between 0 and 1
|
||||
// So defense modifier is between [5, 2.5]
|
||||
return 5 - falloutRatio * 2;
|
||||
return 3 - falloutRatio * 2;
|
||||
}
|
||||
SAMCooldown(): number {
|
||||
return 75;
|
||||
@@ -212,17 +216,19 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
|
||||
defensePostRange(): number {
|
||||
return 30;
|
||||
return 40;
|
||||
}
|
||||
defensePostDefenseBonus(): number {
|
||||
return 5;
|
||||
return 4;
|
||||
}
|
||||
numPlayerTeams(): number {
|
||||
return this._gameConfig.numPlayerTeams ?? 0;
|
||||
}
|
||||
|
||||
spawnNPCs(): boolean {
|
||||
return !this._gameConfig.disableNPCs;
|
||||
}
|
||||
|
||||
disableNukes(): boolean {
|
||||
return this._gameConfig.disableNukes;
|
||||
}
|
||||
@@ -242,12 +248,7 @@ export class DefaultConfig implements Config {
|
||||
return 10000 + 150 * Math.pow(dist, 1.1);
|
||||
}
|
||||
tradeShipSpawnRate(numberOfPorts: number): number {
|
||||
if (numberOfPorts <= 3) return 18;
|
||||
if (numberOfPorts <= 5) return 25;
|
||||
if (numberOfPorts <= 8) return 35;
|
||||
if (numberOfPorts <= 10) return 40;
|
||||
if (numberOfPorts <= 12) return 45;
|
||||
return 50;
|
||||
return Math.round(10 * Math.pow(numberOfPorts, 0.5));
|
||||
}
|
||||
|
||||
unitInfo(type: UnitType): UnitInfo {
|
||||
@@ -274,7 +275,7 @@ export class DefaultConfig implements Config {
|
||||
return {
|
||||
cost: () => 0,
|
||||
territoryBound: false,
|
||||
damage: 250,
|
||||
damage: 200,
|
||||
};
|
||||
case UnitType.SAMMissile:
|
||||
return {
|
||||
@@ -439,26 +440,25 @@ export class DefaultConfig implements Config {
|
||||
defenderTroopLoss: number;
|
||||
tilesPerTickUsed: number;
|
||||
} {
|
||||
let mag = 0;
|
||||
let speed = 0;
|
||||
const terrainModifiers = {
|
||||
[TerrainType.Plains]: { mag: 0.85, speed: 0.75 },
|
||||
[TerrainType.Highland]: { mag: 1, speed: 1 },
|
||||
[TerrainType.Mountain]: { mag: 1.2, speed: 1.4 },
|
||||
} as const;
|
||||
|
||||
const type = gm.terrainType(tileToConquer);
|
||||
switch (type) {
|
||||
case TerrainType.Plains:
|
||||
mag = 85;
|
||||
speed = 16.5;
|
||||
break;
|
||||
case TerrainType.Highland:
|
||||
mag = 100;
|
||||
speed = 20;
|
||||
break;
|
||||
case TerrainType.Mountain:
|
||||
mag = 120;
|
||||
speed = 25;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`terrain type ${type} not supported`);
|
||||
const mod = terrainModifiers[type];
|
||||
if (!mod) {
|
||||
throw new Error(`terrain type ${type} not supported`);
|
||||
}
|
||||
if (defender.isPlayer()) {
|
||||
let mag = mod.mag;
|
||||
let speed = mod.speed;
|
||||
|
||||
const attackerType = attacker.type();
|
||||
const defenderIsPlayer = defender.isPlayer();
|
||||
const defenderType = defenderIsPlayer ? defender.type() : null;
|
||||
|
||||
if (defenderIsPlayer) {
|
||||
for (const dp of gm.nearbyUnits(
|
||||
tileToConquer,
|
||||
gm.config().defensePostRange(),
|
||||
@@ -478,55 +478,51 @@ export class DefaultConfig implements Config {
|
||||
speed *= this.falloutDefenseModifier(falloutRatio);
|
||||
}
|
||||
|
||||
if (attacker.isPlayer() && defender.isPlayer()) {
|
||||
if (attacker.isPlayer() && defenderIsPlayer) {
|
||||
if (attackerType == PlayerType.Human && defenderType == PlayerType.Bot) {
|
||||
mag *= 0.8;
|
||||
}
|
||||
if (
|
||||
attacker.type() == PlayerType.Human &&
|
||||
defender.type() == PlayerType.Bot
|
||||
attackerType == PlayerType.FakeHuman &&
|
||||
defenderType == PlayerType.Bot
|
||||
) {
|
||||
mag *= 0.8;
|
||||
}
|
||||
if (
|
||||
attacker.type() == PlayerType.FakeHuman &&
|
||||
defender.type() == PlayerType.Bot
|
||||
attackerType == PlayerType.Human &&
|
||||
defenderType == PlayerType.FakeHuman
|
||||
) {
|
||||
mag *= 0.8;
|
||||
//mag *= 0.9;
|
||||
//speed *= 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
let largeLossModifier = 1;
|
||||
if (attacker.numTilesOwned() > 100_000) {
|
||||
largeLossModifier = Math.sqrt(100_000 / attacker.numTilesOwned());
|
||||
if (attackerType == PlayerType.Bot) {
|
||||
speed *= 4; // slow bot attacks
|
||||
}
|
||||
let largeSpeedMalus = 1;
|
||||
if (attacker.numTilesOwned() > 75_000) {
|
||||
// sqrt is only exponent 1/2 which doesn't slow enough huge players
|
||||
largeSpeedMalus = (75_000 / attacker.numTilesOwned()) ** 0.6;
|
||||
}
|
||||
|
||||
if (defender.isPlayer()) {
|
||||
if (defenderIsPlayer) {
|
||||
const defenderTroops = defender.troops();
|
||||
const defenderTiles = defender.numTilesOwned();
|
||||
const defenderdensity = defenderTroops / defenderTiles;
|
||||
const attackratio = defenderTroops / attackTroops;
|
||||
return {
|
||||
attackerTroopLoss:
|
||||
within(defender.troops() / attackTroops, 0.6, 2) *
|
||||
mag *
|
||||
0.8 *
|
||||
largeLossModifier *
|
||||
(defender.isTraitor() ? this.traitorDefenseDebuff() : 1),
|
||||
defenderTroopLoss: defender.troops() / defender.numTilesOwned(),
|
||||
mag * 10 +
|
||||
defenderdensity *
|
||||
mag *
|
||||
(defender.isTraitor() ? this.traitorDefenseDebuff() : 1),
|
||||
defenderTroopLoss: defenderdensity,
|
||||
tilesPerTickUsed:
|
||||
within(defender.troops() / (5 * attackTroops), 0.2, 1.5) *
|
||||
27 *
|
||||
within(defenderdensity, 3, 100) ** 0.2 *
|
||||
(10_000 / attackTroops) ** 0.1 *
|
||||
speed *
|
||||
largeSpeedMalus,
|
||||
within(attackratio, 0.3, 20) ** 0.3,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
attackerTroopLoss:
|
||||
attacker.type() == PlayerType.Bot ? mag / 10 : mag / 5,
|
||||
attackerTroopLoss: attackerType == PlayerType.Bot ? mag * 10 : mag * 10,
|
||||
defenderTroopLoss: 0,
|
||||
tilesPerTickUsed: within(
|
||||
(2000 * Math.max(10, speed)) / attackTroops,
|
||||
5,
|
||||
100,
|
||||
),
|
||||
tilesPerTickUsed: 30 * speed, // * (10_000 / attackTroops) ** 0.5,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -538,13 +534,9 @@ export class DefaultConfig implements Config {
|
||||
numAdjacentTilesWithEnemy: number,
|
||||
): number {
|
||||
if (defender.isPlayer()) {
|
||||
return (
|
||||
within(((5 * attackTroops) / defender.troops()) * 2, 0.01, 0.5) *
|
||||
numAdjacentTilesWithEnemy *
|
||||
3
|
||||
);
|
||||
return 10 * numAdjacentTilesWithEnemy;
|
||||
} else {
|
||||
return numAdjacentTilesWithEnemy * 2;
|
||||
return 12 * numAdjacentTilesWithEnemy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,18 +566,18 @@ export class DefaultConfig implements Config {
|
||||
|
||||
startManpower(playerInfo: PlayerInfo): number {
|
||||
if (playerInfo.playerType == PlayerType.Bot) {
|
||||
return 10_000;
|
||||
return 6_000;
|
||||
}
|
||||
if (playerInfo.playerType == PlayerType.FakeHuman) {
|
||||
switch (this._gameConfig.difficulty) {
|
||||
case Difficulty.Easy:
|
||||
return 2_500 * (playerInfo?.nation?.strength ?? 1);
|
||||
return 2_500 + 1000 * (playerInfo?.nation?.strength ?? 1);
|
||||
case Difficulty.Medium:
|
||||
return 5_000 * (playerInfo?.nation?.strength ?? 1);
|
||||
return 6_000 + 2000 * (playerInfo?.nation?.strength ?? 1);
|
||||
case Difficulty.Hard:
|
||||
return 20_000 * (playerInfo?.nation?.strength ?? 1);
|
||||
return 20_000 + 4000 * (playerInfo?.nation?.strength ?? 1);
|
||||
case Difficulty.Impossible:
|
||||
return 50_000 * (playerInfo?.nation?.strength ?? 1);
|
||||
return 50_000 + 8000 * (playerInfo?.nation?.strength ?? 1);
|
||||
}
|
||||
}
|
||||
return this.infiniteTroops() ? 1_000_000 : 25_000;
|
||||
@@ -595,11 +587,11 @@ export class DefaultConfig implements Config {
|
||||
const maxPop =
|
||||
player.type() == PlayerType.Human && this.infiniteTroops()
|
||||
? 1_000_000_000
|
||||
: 2 * (Math.pow(player.numTilesOwned(), 0.6) * 1000 + 50000) +
|
||||
: 1 * (player.numTilesOwned() * 30 + 50000) +
|
||||
player.units(UnitType.City).length * this.cityPopulationIncrease();
|
||||
|
||||
if (player.type() == PlayerType.Bot) {
|
||||
return maxPop / 2;
|
||||
return maxPop / 3;
|
||||
}
|
||||
|
||||
if (player.type() == PlayerType.Human) {
|
||||
@@ -608,11 +600,11 @@ export class DefaultConfig implements Config {
|
||||
|
||||
switch (this._gameConfig.difficulty) {
|
||||
case Difficulty.Easy:
|
||||
return maxPop * 0.5;
|
||||
return maxPop * 0.4;
|
||||
case Difficulty.Medium:
|
||||
return maxPop * 1;
|
||||
return maxPop * 0.7;
|
||||
case Difficulty.Hard:
|
||||
return maxPop * 1.5;
|
||||
return maxPop * 1;
|
||||
case Difficulty.Impossible:
|
||||
return maxPop * 2;
|
||||
}
|
||||
@@ -621,9 +613,15 @@ export class DefaultConfig implements Config {
|
||||
populationIncreaseRate(player: Player): number {
|
||||
const max = this.maxPopulation(player);
|
||||
|
||||
let toAdd = 10 + Math.pow(player.population(), 0.73) / 4;
|
||||
let toAdd =
|
||||
10 +
|
||||
(1400 / max + 1 / 125) * (0.8 * player.troops() + 1.2 * player.workers());
|
||||
const adjustedPop =
|
||||
typeof player.adjustedPopulation === "function"
|
||||
? player.adjustedPopulation()
|
||||
: player.population();
|
||||
|
||||
const ratio = 1 - player.population() / max;
|
||||
const ratio = 1 - adjustedPop / max;
|
||||
toAdd *= ratio;
|
||||
|
||||
if (player.type() == PlayerType.Bot) {
|
||||
@@ -651,11 +649,35 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
|
||||
goldAdditionRate(player: Player): number {
|
||||
return Math.sqrt(player.workers() * player.numTilesOwned()) / 200;
|
||||
const numCities = player.units(UnitType.City).length;
|
||||
const baseCityPopulation = numCities * this.cityPopulationIncrease();
|
||||
|
||||
const totalWorkers = player.workers() ?? 0;
|
||||
const totalPopulation = player.population() ?? 0;
|
||||
const maxPopulation = this.maxPopulation(player) ?? 0;
|
||||
const numTiles = player.numTilesOwned() ?? 0;
|
||||
|
||||
if (totalWorkers <= 0 || totalPopulation <= 0 || maxPopulation <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const populationRatio = totalPopulation / maxPopulation;
|
||||
const adjustedCityPopulation = baseCityPopulation * populationRatio;
|
||||
|
||||
const cityWorkers =
|
||||
(adjustedCityPopulation * totalWorkers) / totalPopulation;
|
||||
const ruralWorkers = totalWorkers - cityWorkers;
|
||||
|
||||
const cityGold = cityWorkers / 2000;
|
||||
const tileGold = (ruralWorkers ** 0.5 * numTiles ** 0.5) / 600;
|
||||
|
||||
const totalGold = 6 * (cityGold + tileGold) ** 0.8;
|
||||
|
||||
return Number.isFinite(totalGold) ? totalGold : 0;
|
||||
}
|
||||
|
||||
troopAdjustmentRate(player: Player): number {
|
||||
const maxDiff = this.maxPopulation(player) / 1000;
|
||||
const maxDiff = this.maxPopulation(player) / 500;
|
||||
const target = player.population() * player.targetTroopRatio();
|
||||
const diff = target - player.troops();
|
||||
if (Math.abs(diff) < maxDiff) {
|
||||
@@ -686,7 +708,7 @@ export class DefaultConfig implements Config {
|
||||
|
||||
// Humans can be population, soldiers attacking, soldiers in boat etc.
|
||||
nukeDeathFactor(humans: number, tilesOwned: number): number {
|
||||
return (5 * humans) / Math.max(1, tilesOwned);
|
||||
return (2 * humans) / Math.max(1, tilesOwned);
|
||||
}
|
||||
|
||||
structureMinDist(): number {
|
||||
@@ -711,7 +733,7 @@ export class DefaultConfig implements Config {
|
||||
}
|
||||
|
||||
defensePostShellAttackRate(): number {
|
||||
return 100;
|
||||
return 120;
|
||||
}
|
||||
|
||||
safeFromPiratesCooldownMax(): number {
|
||||
|
||||
Reference in New Issue
Block a user