diff --git a/TODO.txt b/TODO.txt
index 3e4235018..64f07eb3e 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -191,8 +191,10 @@
* NPC builds ports DONE 11/20/2024
* BUG: fix matchmaking DONE 11/22/2024
* destroyer can capture trade ships DONE 11/22/2024
-* have bots recapture after nuclear blast
-*
+* have bots recapture after nuclear blast DONE 11/24/2022
+* don't capture trade ships if allied with either port
+* make ports cost more for more ports
+* BUG: Destroyers destroy instead of capture trade ships
* NPC has relations
* make NPC difficult scale better (not just start troops)
* add battleship
diff --git a/src/client/graphics/layers/radial/BuildMenu.ts b/src/client/graphics/layers/radial/BuildMenu.ts
index d6b524cc3..89314af73 100644
--- a/src/client/graphics/layers/radial/BuildMenu.ts
+++ b/src/client/graphics/layers/radial/BuildMenu.ts
@@ -191,7 +191,7 @@ export class BuildMenu extends LitElement {
${item.unitType}
- ${renderNumber(this.game ? this.game.unitInfo(item.unitType).cost : 0)}
+ ${renderNumber(this.game && this.myPlayer ? this.game.unitInfo(item.unitType).cost(this.myPlayer) : 0)}
diff --git a/src/client/index.html b/src/client/index.html
index 94f83e584..f99c8ab15 100644
--- a/src/client/index.html
+++ b/src/client/index.html
@@ -28,7 +28,7 @@
diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts
index 6462fac33..fc68b8816 100644
--- a/src/core/configuration/DefaultConfig.ts
+++ b/src/core/configuration/DefaultConfig.ts
@@ -12,43 +12,43 @@ export class DefaultConfig implements Config {
}
tradeShipGold(src: Unit, dst: Unit): Gold {
const dist = manhattanDist(src.tile().cell(), dst.tile().cell())
- return 10000 + 5 * dist
+ return 10000 + 50 * dist
}
unitInfo(type: UnitType): UnitInfo {
switch (type) {
case UnitType.TransportShip:
return {
- cost: 0,
+ cost: () => 0,
territoryBound: false
}
case UnitType.Destroyer:
return {
- cost: 250_000,
+ cost: () => 250_000,
territoryBound: false
}
case UnitType.Port:
return {
- cost: 250_000,
+ cost: (p: Player) => (p.units(UnitType.Port).length + 1) * 250_000,
territoryBound: true
}
case UnitType.AtomBomb:
return {
- cost: 1_000_000,
+ cost: () => 1_000_000,
territoryBound: false
}
case UnitType.HydrogenBomb:
return {
- cost: 5_000_000,
+ cost: () => 5_000_000,
territoryBound: false
}
case UnitType.TradeShip:
return {
- cost: 0,
+ cost: () => 0,
territoryBound: false
}
case UnitType.MissileSilo:
return {
- cost: 1_000_000,
+ cost: () => 2_500_000,
territoryBound: true
}
default:
@@ -173,7 +173,7 @@ export class DefaultConfig implements Config {
return 10000
}
if (playerInfo.playerType == PlayerType.FakeHuman) {
- return 1000 // start troops * strength * difficulty
+ return 2000 // start troops * strength * difficulty
}
return 25000
}
@@ -207,7 +207,7 @@ export class DefaultConfig implements Config {
}
goldAdditionRate(player: Player): number {
- return Math.sqrt(player.workers() * player.numTilesOwned()) / 600
+ return Math.sqrt(player.workers() * player.numTilesOwned()) / 250
}
troopAdjustmentRate(player: Player): number {
diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts
index 700a32ce3..fddd18524 100644
--- a/src/core/configuration/DevConfig.ts
+++ b/src/core/configuration/DevConfig.ts
@@ -1,10 +1,11 @@
-import { PlayerInfo, UnitInfo, UnitType } from "../game/Game";
+import { Player, PlayerInfo, UnitInfo, UnitType } from "../game/Game";
import { DefaultConfig } from "./DefaultConfig";
export const devConfig = new class extends DefaultConfig {
unitInfo(type: UnitType): UnitInfo {
const info = super.unitInfo(type)
- info.cost = 0
+ const oldCost = info.cost
+ info.cost = (p: Player) => oldCost(p) / 100
return info
}
diff --git a/src/core/execution/FakeHumanExecution.ts b/src/core/execution/FakeHumanExecution.ts
index 0cfd4f0c8..79676563a 100644
--- a/src/core/execution/FakeHumanExecution.ts
+++ b/src/core/execution/FakeHumanExecution.ts
@@ -61,11 +61,7 @@ export class FakeHumanExecution implements Execution {
return
}
- if (this.player.troops() < this.mg.config().maxPopulation(this.player) / 4) {
- return
- }
-
- if (ticks % this.random.nextInt(10, 30) != 0) {
+ if (ticks % this.random.nextInt(40, 80) != 0) {
return
}
@@ -142,7 +138,7 @@ export class FakeHumanExecution implements Execution {
}
if (this.enemy) {
- if (this.player.sharesBorderWith(this.enemy)) {
+ if (this.player.sharesBorderWith(this.enemy) && !this.player.isAlliedWith(this.enemy)) {
this.sendAttack(this.enemy)
}
return
@@ -151,7 +147,7 @@ export class FakeHumanExecution implements Execution {
}
private handleUnits() {
- if (this.player.units(UnitType.Port).length == 0 && this.player.gold() > this.mg.unitInfo(UnitType.Port).cost) {
+ if (this.player.units(UnitType.Port).length == 0 && this.player.gold() > this.mg.unitInfo(UnitType.Port).cost(this.player)) {
const oceanTiles = Array.from(this.player.borderTiles()).filter(t => t.isOceanShore())
if (oceanTiles.length > 0) {
const buildTile = this.random.randElement(oceanTiles)
@@ -162,25 +158,10 @@ export class FakeHumanExecution implements Execution {
handleAllianceRequests() {
for (const req of this.player.incomingAllianceRequests()) {
-
- if (req.requestor().numTilesOwned() > this.player.numTilesOwned() * 2) {
- req.accept()
- continue
- }
- if (req.recipient().numTilesOwned() > this.player.numTilesOwned()) {
- if (this.random.chance(2)) {
- req.accept()
- } else {
- req.reject()
- this.rejected.add(req.recipient())
- }
- continue
- }
- if (this.random.chance(5)) {
- req.accept()
- } else {
+ if (req.requestor().isTraitor() || req.requestor().alliances().length >= 3) {
req.reject()
- this.rejected.add(req.recipient())
+ } else {
+ req.accept()
}
}
}
diff --git a/src/core/execution/PortExecution.ts b/src/core/execution/PortExecution.ts
index dd98343b8..97e729345 100644
--- a/src/core/execution/PortExecution.ts
+++ b/src/core/execution/PortExecution.ts
@@ -86,7 +86,7 @@ export class PortExecution implements Execution {
const portConnections = Array.from(this.portPaths.keys())
- if (portConnections.length > 0 && this.random.chance(250 * this.player().units(UnitType.Port).length)) {
+ if (portConnections.length > 0 && this.random.chance(250)) {
const port = this.random.randElement(portConnections)
const path = this.portPaths.get(port)
if (path != null) {
diff --git a/src/core/execution/TradeShipExecution.ts b/src/core/execution/TradeShipExecution.ts
index 6b0ae03b5..d70aa625c 100644
--- a/src/core/execution/TradeShipExecution.ts
+++ b/src/core/execution/TradeShipExecution.ts
@@ -44,6 +44,11 @@ export class TradeShipExecution implements Execution {
this.active = false
return
}
+ if (!this.dstPort.isActive() || !this.tradeShip.owner().isAlliedWith(this.dstPort.owner())) {
+ this.tradeShip.delete()
+ this.active = false
+ return
+ }
if (this.origOwner != this.tradeShip.owner()) {
// Store as vairable in case ship is recaptured by previous owner
@@ -82,17 +87,11 @@ export class TradeShipExecution implements Execution {
}
return
}
- if(!this.dstPort.isActive() || !this.tradeShip.owner().isAlliedWith(this.dstPort.owner())) {
- this.tradeShip.delete()
- this.active = false
- return
- }
if (this.index >= this.path.length) {
this.active = false
- const dist = manhattanDist(this.srcPort.tile().cell(), this.dstPort.tile().cell())
- const gold = dist * dist
+ const gold = this.mg.config().tradeShipGold(this.srcPort, this.dstPort)
this.srcPort.owner().addGold(gold)
this.dstPort.owner().addGold(gold)
this.mg.displayMessage(`Trade ship from ${this.tradeShip.owner().displayName()} has reached your port, giving you ${renderNumber(gold)} gold`, MessageType.SUCCESS, this.dstPort.owner().id())
diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts
index ad015af17..ce0a62a2b 100644
--- a/src/core/game/Game.ts
+++ b/src/core/game/Game.ts
@@ -23,7 +23,7 @@ export enum GameMap {
}
export interface UnitInfo {
- cost: Gold
+ cost: (player: Player) => Gold
// Determines if its owner changes when its tile is conquered.
territoryBound: boolean
}
diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts
index 3b5fa3e7d..d69498502 100644
--- a/src/core/game/PlayerImpl.ts
+++ b/src/core/game/PlayerImpl.ts
@@ -334,7 +334,7 @@ export class PlayerImpl implements MutablePlayer {
buildUnit(type: UnitType, troops: number, spawnTile: Tile): UnitImpl {
const b = new UnitImpl(type, this.gs, spawnTile, troops, this);
this._units.push(b);
- this.removeGold(this.gs.unitInfo(type).cost)
+ this.removeGold(this.gs.unitInfo(type).cost(this))
this.removeTroops(troops)
this.gs.fireUnitUpdateEvent(b, b.tile());
return b;
@@ -342,7 +342,7 @@ export class PlayerImpl implements MutablePlayer {
canBuild(unitType: UnitType, targetTile: Tile): Tile | false {
- const cost = this.gs.unitInfo(unitType).cost
+ const cost = this.gs.unitInfo(unitType).cost(this)
if (!this.isAlive() || this.gold() < cost) {
return false
}