The clown is gone! 🤡 Nations send much better emojis now (#2696)

## Description:

Previously, nations just spammed these two rather toxic emojis: 🤡😡

They now send fewer emojis while attacking, and the clown emoji is
reserved for special cases.

They got the ability to send emojis in much more cases:
- Human didn't donate enough for relation update
- Human did donate an ok amount
- Human did donate a lot
- Responding to emojis that they get sent from a human
- Nuke sent
- MIRV sent
- Retaliation warship sent
- Traitor tries to ally
- Threat asks for / accepts an alliance request
- Disliked human tries to ally
- Friendly human tries to ally
- They are getting attacked by very much troops
- They are getting attacked by very little troops
- Congratulating the winner
- Bragging with their crown
- Charming their allies
- Clown-Emoting traitors
- Easteregg: Sending a rat emoji to very small humans

## 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

## Please put your Discord username so you can be contacted if a bug or
regression is found:

FloPinguin

---------

Co-authored-by: iamlewis <lewismmmm@gmail.com>
This commit is contained in:
FloPinguin
2025-12-26 13:07:31 -08:00
committed by GitHub
co-authored by iamlewis
parent e45839fbc2
commit 5d52f73278
12 changed files with 441 additions and 54 deletions
@@ -9,17 +9,25 @@ import { PseudoRandom } from "../../PseudoRandom";
import { assertNever } from "../../Util";
import { AllianceExtensionExecution } from "../alliance/AllianceExtensionExecution";
import { AllianceRequestExecution } from "../alliance/AllianceRequestExecution";
import {
EMOJI_CONFUSED,
EMOJI_HANDSHAKE,
EMOJI_LOVE,
EMOJI_SCARED_OF_THREAT,
NationEmojiBehavior,
} from "./NationEmojiBehavior";
export class NationAllianceBehavior {
constructor(
private random: PseudoRandom,
private game: Game,
private player: Player,
private emojiBehavior: NationEmojiBehavior,
) {}
handleAllianceRequests() {
for (const req of this.player.incomingAllianceRequests()) {
if (this.getAllianceRequestDecision(req.requestor())) {
if (this.getAllianceDecision(req.requestor(), true)) {
req.accept();
} else {
req.reject();
@@ -34,7 +42,7 @@ export class NationAllianceBehavior {
if (!alliance.onlyOneAgreedToExtend()) continue;
const human = alliance.other(this.player);
if (!this.getAllianceRequestDecision(human)) continue;
if (!this.getAllianceDecision(human, true)) continue;
this.game.addExecution(
new AllianceExtensionExecution(this.player, human.id()),
@@ -54,7 +62,7 @@ export class NationAllianceBehavior {
this.random.chance(20) &&
isAcceptablePlayerType(enemy) &&
this.player.canSendAllianceRequest(enemy) &&
this.getAllianceRequestDecision(enemy)
this.getAllianceDecision(enemy, false)
) {
this.game.addExecution(
new AllianceRequestExecution(this.player, enemy.id()),
@@ -63,27 +71,45 @@ export class NationAllianceBehavior {
}
}
private getAllianceRequestDecision(otherPlayer: Player): boolean {
private getAllianceDecision(
otherPlayer: Player,
isResponse: boolean,
): boolean {
// Easy (dumb) nations sometimes get confused and accept/reject randomly (Just like dumb humans do)
if (this.isConfused()) {
return this.random.chance(2);
}
// Nearly always reject traitors
if (otherPlayer.isTraitor() && this.random.nextInt(0, 100) >= 10) {
if (isResponse && this.random.chance(3)) {
this.emojiBehavior.sendEmoji(otherPlayer, EMOJI_CONFUSED);
}
return false;
}
// Before caring about the relation, first check if the otherPlayer is a threat
// Easy (dumb) nations are blinded by hatred, they don't care about threats, they care about the relation
// Impossible (smart) nations on the other hand are analyzing the facts
if (this.isAlliancePartnerThreat(otherPlayer)) {
if (!isResponse && this.random.chance(3)) {
this.emojiBehavior.sendEmoji(otherPlayer, EMOJI_SCARED_OF_THREAT);
}
if (isResponse && this.random.chance(3)) {
this.emojiBehavior.sendEmoji(otherPlayer, EMOJI_LOVE);
}
return true;
}
// Reject if relation is bad
if (this.player.relation(otherPlayer) < Relation.Neutral) {
if (isResponse && this.random.chance(3)) {
this.emojiBehavior.sendEmoji(otherPlayer, EMOJI_CONFUSED);
}
return false;
}
// Maybe accept if relation is friendly
if (this.isAlliancePartnerFriendly(otherPlayer)) {
if (this.random.chance(3)) {
this.emojiBehavior.sendEmoji(otherPlayer, EMOJI_HANDSHAKE);
}
return true;
}
// Reject if we already have some alliances, we don't want to ally with the entire map