Named the actors behind government news
This commit is contained in:
@@ -70,18 +70,29 @@ export function percent(value) {
|
||||
return `${value < 0 ? "−" : "+"}${(Math.abs(value) * 100).toFixed(1)}%`;
|
||||
}
|
||||
|
||||
// Renders one news entry as text, resolving civ indices to names and demonyms.
|
||||
// Renders one news entry as text. Government actions name the specific actors
|
||||
// doing them — "French troops", "French scientists" — rather than the nation as
|
||||
// a whole, and the victim or target is named in the people's form ("the
|
||||
// Vietnamese").
|
||||
export function describeNews(entry, civs) {
|
||||
const name = (index) => (civs[index] ? civs[index].name : `Nation ${index + 1}`);
|
||||
// The attributive form of a nation, for putting before an actor noun. It
|
||||
// falls back to the demonym, which doubles as an adjective for most of them;
|
||||
// the few person-nouns (New Zealander, New Hampshirite) carry an explicit one.
|
||||
const adjective = (index) => {
|
||||
const civ = civs[index];
|
||||
if (!civ) return `Nation ${index + 1}`;
|
||||
return civ.adjective || civ.demonym || civ.name;
|
||||
};
|
||||
const people = (index) => {
|
||||
const civ = civs[index];
|
||||
return civ && civ.demonym ? `The ${civ.demonym}` : name(index);
|
||||
return civ && civ.demonym ? `the ${civ.demonym}` : name(index);
|
||||
};
|
||||
switch (entry.type) {
|
||||
case "war":
|
||||
return `${people(entry.actor)} declared war on ${name(entry.target)}`;
|
||||
return `${adjective(entry.actor)} leaders have declared war on ${name(entry.target)}`;
|
||||
case "capture":
|
||||
return `${people(entry.to)} captured ${entry.city} from ${name(entry.from)}`;
|
||||
return `${adjective(entry.to)} troops have captured ${entry.city} from ${people(entry.from)}`;
|
||||
case "policy": {
|
||||
const policy = policyById(entry.policy);
|
||||
const policyName = policy ? policy.name : entry.policy;
|
||||
@@ -89,12 +100,12 @@ export function describeNews(entry, civs) {
|
||||
civs[entry.ethnicity] && civs[entry.ethnicity].demonym
|
||||
? `the ${civs[entry.ethnicity].demonym}`
|
||||
: name(entry.ethnicity);
|
||||
return `${name(entry.civ)} enacted ${policyName} for ${who}`;
|
||||
return `${adjective(entry.civ)} lawmakers have enacted ${policyName} for ${who}`;
|
||||
}
|
||||
case "technology":
|
||||
return entry.repeatable
|
||||
? `${name(entry.civ)} improved ${entry.name}`
|
||||
: `${name(entry.civ)} discovered ${entry.name}`;
|
||||
? `${adjective(entry.civ)} scientists have improved ${entry.name}`
|
||||
: `${adjective(entry.civ)} scientists have discovered ${entry.name}`;
|
||||
case "join":
|
||||
return `${entry.player} took control of ${name(entry.civ)}`;
|
||||
default:
|
||||
|
||||
+44
-3
@@ -1,7 +1,7 @@
|
||||
import { TestCase } from "./framework/test_case.js";
|
||||
import { setupDom, teardownDom } from "./framework/dom.js";
|
||||
import { CityModal, NationModal, ConfirmModal, NewsModal } from "../client/js/modals.js";
|
||||
import { buildingEffectText } from "../client/js/modals/format.js";
|
||||
import { buildingEffectText, describeNews } from "../client/js/modals/format.js";
|
||||
import { BUILDINGS, GOVERNMENTS, TECHNOLOGIES, PROTO_UNITS } from "../shared/data.js";
|
||||
|
||||
export class CityModalTest extends TestCase {
|
||||
@@ -640,9 +640,13 @@ export class NewsModalTest extends TestCase {
|
||||
modal.show(news, civs);
|
||||
const items = env.$("#news-list .news-item");
|
||||
this.assertSize(items, 2);
|
||||
this.assertTrue(items.eq(0).find(".news-text").text().includes("The French captured Lyon from Britain"));
|
||||
this.assertTrue(
|
||||
items.eq(0).find(".news-text").text().includes("French troops have captured Lyon from the British")
|
||||
);
|
||||
this.assertTrue(items.eq(0).find(".news-date").text().includes("05:00"));
|
||||
this.assertTrue(items.eq(1).find(".news-text").text().includes("The French declared war on Britain"));
|
||||
this.assertTrue(
|
||||
items.eq(1).find(".news-text").text().includes("French leaders have declared war on Britain")
|
||||
);
|
||||
|
||||
modal.refresh([], civs);
|
||||
this.assertEqual(env.$("#news-list .news-item").length, 0);
|
||||
@@ -653,4 +657,41 @@ export class NewsModalTest extends TestCase {
|
||||
teardownDom(env);
|
||||
}
|
||||
}
|
||||
|
||||
test_news_names_the_actors_doing_the_action() {
|
||||
const civs = [
|
||||
{ name: "France", demonym: "French" },
|
||||
{ name: "Vietnam", demonym: "Vietnamese" },
|
||||
{ name: "Aotearoa", demonym: "New Zealander", adjective: "New Zealand" },
|
||||
];
|
||||
this.assertEqual(
|
||||
describeNews({ type: "capture", city: "Saigon", from: 1, to: 0 }, civs),
|
||||
"French troops have captured Saigon from the Vietnamese"
|
||||
);
|
||||
this.assertEqual(
|
||||
describeNews({ type: "technology", civ: 0, name: "Radio" }, civs),
|
||||
"French scientists have discovered Radio"
|
||||
);
|
||||
this.assertEqual(
|
||||
describeNews({ type: "technology", civ: 0, name: "Railways", repeatable: true }, civs),
|
||||
"French scientists have improved Railways"
|
||||
);
|
||||
this.assertEqual(
|
||||
describeNews({ type: "war", actor: 0, target: 1 }, civs),
|
||||
"French leaders have declared war on Vietnam"
|
||||
);
|
||||
this.assertEqual(
|
||||
describeNews({ type: "policy", civ: 0, policy: "some_policy", ethnicity: 1 }, civs),
|
||||
"French lawmakers have enacted some_policy for the Vietnamese"
|
||||
);
|
||||
this.assertEqual(
|
||||
describeNews({ type: "join", player: "Alice", civ: 1 }, civs),
|
||||
"Alice took control of Vietnam"
|
||||
);
|
||||
// Person-noun demonyms carry an explicit attributive form.
|
||||
this.assertEqual(
|
||||
describeNews({ type: "technology", civ: 2, name: "Radio" }, civs),
|
||||
"New Zealand scientists have discovered Radio"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user