-
Notifications
You must be signed in to change notification settings - Fork 1k
feat: allow trade ships to trade with own ports at reduced gold #3785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,14 +21,17 @@ export class TradeShipExecution implements Execution { | |
| private tilesTraveled = 0; | ||
| private motionPlanId = 1; | ||
| private motionPlanDst: TileRef | null = null; | ||
| private readonly isSelfTrade: boolean; | ||
|
|
||
| private static _staggerCounter = 0; | ||
|
|
||
| constructor( | ||
| private origOwner: Player, | ||
| private srcPort: Unit, | ||
| private _dstPort: Unit, | ||
| ) {} | ||
| ) { | ||
| this.isSelfTrade = srcPort.owner() === _dstPort.owner(); | ||
| } | ||
|
|
||
| init(mg: Game, ticks: number): void { | ||
| this.mg = mg; | ||
|
|
@@ -72,22 +75,30 @@ export class TradeShipExecution implements Execution { | |
| } | ||
|
|
||
| // If a player captures another player's port while trading we should delete | ||
| // the ship. | ||
| if (dstPortOwner.id() === this.srcPort.owner().id()) { | ||
| // the ship — but not if it was intentionally a self-trade. | ||
| if (!this.isSelfTrade && dstPortOwner.id() === this.srcPort.owner().id()) { | ||
| this.tradeShip.delete(false); | ||
| this.active = false; | ||
| return; | ||
| } | ||
|
|
||
| if ( | ||
| !this.wasCaptured && | ||
| !this.isSelfTrade && | ||
| (!this._dstPort.isActive() || !tradeShipOwner.canTrade(dstPortOwner)) | ||
| ) { | ||
| this.tradeShip.delete(false); | ||
| this.active = false; | ||
| return; | ||
| } | ||
|
|
||
| // For self-trade, still check if the destination port is active | ||
| if (this.isSelfTrade && !this._dstPort.isActive()) { | ||
| this.tradeShip.delete(false); | ||
| this.active = false; | ||
| return; | ||
| } | ||
|
Comment on lines
+77
to
91
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Captured self-trade ship cannot reroute when destination is also lost. For non-self trades, the Mirror the non-self path so capture takes precedence over the self-trade ownership check. 🛡️ Suggested fix- const dstActive = this._dstPort.isActive();
- const shouldCancel =
- // Non-self-trade: cancel if destination port was captured back, or
- // (not yet captured) if trade is no longer viable
- (!this.isSelfTrade &&
- (dstPortOwner.id() === this.srcPort.owner().id() ||
- (!this.wasCaptured &&
- (!dstActive || !tradeShipOwner.canTrade(dstPortOwner))))) ||
- // Self-trade: cancel if destination port is no longer active or was captured
- (this.isSelfTrade &&
- (!dstActive || dstPortOwner !== this.srcPort.owner()));
- if (shouldCancel) {
- this.cancelTrade();
- return;
- }
+ const dstActive = this._dstPort.isActive();
+ const srcOwnerId = this.srcPort.owner().id();
+ let shouldCancel = false;
+ if (this.isSelfTrade) {
+ // Self-trade: cancel only if not yet captured and the round-trip
+ // is no longer possible (dst inactive or no longer owned by us).
+ shouldCancel =
+ !this.wasCaptured &&
+ (!dstActive || dstPortOwner.id() !== srcOwnerId);
+ } else if (this.wasCaptured) {
+ // Captured cross-player ship: only cancel if the source player
+ // already retook the destination.
+ shouldCancel = dstPortOwner.id() === srcOwnerId;
+ } else {
+ shouldCancel =
+ dstPortOwner.id() === srcOwnerId ||
+ !dstActive ||
+ !tradeShipOwner.canTrade(dstPortOwner);
+ }
+ if (shouldCancel) {
+ this.cancelTrade();
+ return;
+ }This also flattens the condition into three clear cases, which is easier to read than the combined boolean expression. 🤖 Prompt for AI Agents |
||
|
|
||
| const curTile = this.tradeShip.tile(); | ||
|
|
||
| if ( | ||
|
|
@@ -168,7 +179,7 @@ export class TradeShipExecution implements Execution { | |
| private complete() { | ||
| this.active = false; | ||
| this.tradeShip!.delete(false); | ||
| const gold = this.mg | ||
| let gold = this.mg | ||
| .config() | ||
| .tradeShipGold(this.tilesTraveled, this.tradeShip!.owner()); | ||
|
|
||
|
|
@@ -188,6 +199,25 @@ export class TradeShipExecution implements Execution { | |
| this.mg | ||
| .stats() | ||
| .boatCapturedTrade(this.tradeShip!.owner(), this.origOwner, gold); | ||
| } else if (this.isSelfTrade) { | ||
| // Self-trade: reduced gold, credited once | ||
| const multiplier = this.mg.config().tradeShipSelfGoldMultiplier(); | ||
| gold = BigInt(Math.floor(Number(gold) * multiplier)); | ||
| this.srcPort.owner().addGold(gold, this._dstPort.tile()); | ||
| this.mg.displayMessage( | ||
| "events_display.received_gold_from_trade", | ||
| MessageType.RECEIVED_GOLD_FROM_TRADE, | ||
| this.srcPort.owner().id(), | ||
| gold, | ||
| { | ||
| gold: renderNumber(gold), | ||
| name: this.srcPort.owner().displayName(), | ||
| }, | ||
| ); | ||
| // Record stats | ||
| this.mg | ||
| .stats() | ||
| .boatArriveTrade(this.srcPort.owner(), this._dstPort.owner(), gold); | ||
|
Comment on lines
+197
to
+215
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Self-trade message shows the player their own name. The cross-player branch below shows the source the destination player's name and vice versa. Here the recipient is 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eh, This should be fine.. Too many different chat labels might get confusing for the player
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(⳹´・ω・)ノ 🧠 Learnings used |
||
| } else { | ||
| this.srcPort.owner().addGold(gold); | ||
| this._dstPort.owner().addGold(gold, this._dstPort.tile()); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.