1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
30 enum event_section_n
{
47 * Information about all event sections, matching the enum above.
49 static const char *event_sections
[] = {
50 /* TRANS: This and following strings are prefixes for event names, which
51 * replace %s. For instance, "Technology: Selected New Goal". */
53 N_("Improvement: %s"),
55 N_("Diplomat Action: %s"),
56 N_("Enemy Diplomat: %s"),
62 /* TRANS: "Vote" as a process */
68 #define GEN_EV(event, section, descr) { #event, NULL, section, descr, NULL, event }
71 * Holds information about all event types. The entries don't have
73 * Every E_* event defined in common/events.h should have an entry here.
76 const char *enum_name
;
78 enum event_section_n esn
;
81 enum event_type event
;
83 /* TRANS: this and following strings are names for events which cause the
84 * server to generate messages. They are used in configuring how the client
85 * handles the different types of messages. Some of them will be displayed
86 * with prefixes, such as "Technology: Learned From Great Library". */
87 GEN_EV(E_TECH_GAIN
, E_S_ADVANCE
, N_("Learned From Great Library")),
88 GEN_EV(E_TECH_LEARNED
, E_S_ADVANCE
, N_("Learned New Tech")),
89 GEN_EV(E_TECH_GOAL
, E_S_ADVANCE
, N_("Selected New Goal")),
90 GEN_EV(E_IMP_BUY
, E_S_BUILD
, N_("Bought")),
91 GEN_EV(E_IMP_BUILD
, E_S_BUILD
, N_("Built")),
92 GEN_EV(E_IMP_AUCTIONED
, E_S_BUILD
, N_("Forced to Sell")),
93 GEN_EV(E_IMP_AUTO
, E_S_BUILD
, N_("New Improvement Selected")),
94 GEN_EV(E_IMP_SOLD
, E_S_BUILD
, N_("Sold")),
95 GEN_EV(E_CITY_CANTBUILD
, E_S_CITY
, N_("Building Unavailable Item")),
96 GEN_EV(E_CITY_LOST
, E_S_CITY
, N_("Captured/Destroyed")),
97 GEN_EV(E_CITY_LOVE
, E_S_CITY
, N_("Celebrating")),
98 GEN_EV(E_CITY_DISORDER
, E_S_CITY
, N_("Civil Disorder")),
99 GEN_EV(E_CITY_FAMINE
, E_S_CITY
, N_("Famine")),
100 GEN_EV(E_CITY_FAMINE_FEARED
, E_S_CITY
, N_("Famine Feared")),
101 GEN_EV(E_CITY_GROWTH
, E_S_CITY
, N_("Growth")),
102 GEN_EV(E_CITY_MAY_SOON_GROW
, E_S_CITY
, N_("May Soon Grow")),
103 GEN_EV(E_CITY_AQUEDUCT
, E_S_CITY
, N_("Needs Aqueduct")),
104 GEN_EV(E_CITY_AQ_BUILDING
, E_S_CITY
, N_("Needs Aqueduct Being Built")),
105 GEN_EV(E_CITY_NORMAL
, E_S_CITY
, N_("Normal")),
106 GEN_EV(E_CITY_NUKED
, E_S_CITY
, N_("Nuked")),
107 GEN_EV(E_CITY_CMA_RELEASE
, E_S_CITY
, N_("Released from citizen governor")),
108 GEN_EV(E_CITY_GRAN_THROTTLE
, E_S_CITY
, N_("Suggest Growth Throttling")),
109 GEN_EV(E_CITY_TRANSFER
, E_S_CITY
, N_("Transfer")),
110 GEN_EV(E_CITY_BUILD
, E_S_CITY
, N_("Was Built")),
111 GEN_EV(E_CITY_PLAGUE
, E_S_CITY
, N_("Has Plague")),
112 GEN_EV(E_CITY_RADIUS_SQ
, E_S_CITY
, N_("City Map changed")),
113 GEN_EV(E_WORKLIST
, E_S_CITY
, N_("Worklist Events")),
114 GEN_EV(E_CITY_PRODUCTION_CHANGED
, E_S_CITY
, N_("Production changed")),
115 GEN_EV(E_DISASTER
, E_S_CITY
, N_("Disaster")),
116 GEN_EV(E_MY_DIPLOMAT_BRIBE
, E_S_D_ME
, N_("Bribe")),
117 GEN_EV(E_DIPLOMATIC_INCIDENT
, E_S_D_ME
, N_("Caused Incident")),
118 GEN_EV(E_MY_DIPLOMAT_ESCAPE
, E_S_D_ME
, N_("Escape")),
119 GEN_EV(E_MY_DIPLOMAT_EMBASSY
, E_S_D_ME
, N_("Embassy")),
120 GEN_EV(E_MY_DIPLOMAT_FAILED
, E_S_D_ME
, N_("Failed")),
121 GEN_EV(E_MY_DIPLOMAT_INCITE
, E_S_D_ME
, N_("Incite")),
122 GEN_EV(E_MY_DIPLOMAT_POISON
, E_S_D_ME
, N_("Poison")),
123 GEN_EV(E_MY_DIPLOMAT_SABOTAGE
, E_S_D_ME
, N_("Sabotage")),
124 GEN_EV(E_MY_DIPLOMAT_THEFT
, E_S_D_ME
, N_("Theft")),
125 GEN_EV(E_ENEMY_DIPLOMAT_BRIBE
, E_S_D_THEM
, N_("Bribe")),
126 GEN_EV(E_ENEMY_DIPLOMAT_EMBASSY
, E_S_D_THEM
, N_("Embassy")),
127 GEN_EV(E_ENEMY_DIPLOMAT_FAILED
, E_S_D_THEM
, N_("Failed")),
128 GEN_EV(E_ENEMY_DIPLOMAT_INCITE
, E_S_D_THEM
, N_("Incite")),
129 GEN_EV(E_ENEMY_DIPLOMAT_POISON
, E_S_D_THEM
, N_("Poison")),
130 GEN_EV(E_ENEMY_DIPLOMAT_SABOTAGE
, E_S_D_THEM
, N_("Sabotage")),
131 GEN_EV(E_ENEMY_DIPLOMAT_THEFT
, E_S_D_THEM
, N_("Theft")),
132 GEN_EV(E_GLOBAL_ECO
, E_S_GLOBAL
, N_("Eco-Disaster")),
133 GEN_EV(E_NUKE
, E_S_GLOBAL
, N_("Nuke Detonated")),
134 GEN_EV(E_HUT_BARB
, E_S_HUT
, N_("Barbarians in a Hut Roused")),
135 GEN_EV(E_HUT_CITY
, E_S_HUT
, N_("City Founded from Hut")),
136 GEN_EV(E_HUT_GOLD
, E_S_HUT
, N_("Gold Found in Hut")),
137 GEN_EV(E_HUT_BARB_KILLED
, E_S_HUT
, N_("Killed by Barbarians in a Hut")),
138 GEN_EV(E_HUT_MERC
, E_S_HUT
, N_("Mercenaries Found in Hut")),
139 GEN_EV(E_HUT_SETTLER
, E_S_HUT
, N_("Settler Found in Hut")),
140 GEN_EV(E_HUT_TECH
, E_S_HUT
, N_("Tech Found in Hut")),
141 GEN_EV(E_HUT_BARB_CITY_NEAR
, E_S_HUT
, N_("Unit Spared by Barbarians")),
142 GEN_EV(E_UPRISING
, E_S_NATION
, N_("Barbarian Uprising")),
143 GEN_EV(E_CIVIL_WAR
, E_S_NATION
, N_("Civil War")),
144 GEN_EV(E_ANARCHY
, E_S_NATION
, N_("Collapse to Anarchy")),
145 GEN_EV(E_FIRST_CONTACT
, E_S_NATION
, N_("First Contact")),
146 GEN_EV(E_NEW_GOVERNMENT
, E_S_NATION
, N_("Learned New Government")),
147 GEN_EV(E_LOW_ON_FUNDS
, E_S_NATION
, N_("Low Funds")),
148 GEN_EV(E_POLLUTION
, E_S_NATION
, N_("Pollution")),
149 GEN_EV(E_REVOLT_DONE
, E_S_NATION
, N_("Revolution Ended")),
150 GEN_EV(E_REVOLT_START
, E_S_NATION
, N_("Revolution Started")),
151 GEN_EV(E_SPACESHIP
, E_S_NATION
, N_("Spaceship Events")),
152 GEN_EV(E_TREATY_ALLIANCE
, E_S_TREATY
, N_("Alliance")),
153 GEN_EV(E_TREATY_BROKEN
, E_S_TREATY
, N_("Broken")),
154 GEN_EV(E_TREATY_CEASEFIRE
, E_S_TREATY
, N_("Cease-fire")),
155 GEN_EV(E_TREATY_EMBASSY
, E_S_TREATY
, N_("Embassy")),
156 GEN_EV(E_TREATY_PEACE
, E_S_TREATY
, N_("Peace")),
157 GEN_EV(E_TREATY_SHARED_VISION
,E_S_TREATY
, N_("Shared Vision")),
158 GEN_EV(E_UNIT_LOST_ATT
, E_S_UNIT
, N_("Attack Failed")),
159 GEN_EV(E_UNIT_WIN_ATT
, E_S_UNIT
, N_("Attack Succeeded")),
160 GEN_EV(E_UNIT_BUY
, E_S_UNIT
, N_("Bought")),
161 GEN_EV(E_UNIT_BUILT
, E_S_UNIT
, N_("Built")),
162 GEN_EV(E_UNIT_LOST_DEF
, E_S_UNIT
, N_("Defender Destroyed")),
163 GEN_EV(E_UNIT_WIN
, E_S_UNIT
, N_("Defender Survived")),
164 GEN_EV(E_UNIT_BECAME_VET
, E_S_UNIT
, N_("Promoted to Veteran")),
165 GEN_EV(E_UNIT_LOST_MISC
, E_S_UNIT
, N_("Lost outside battle")),
166 GEN_EV(E_UNIT_UPGRADED
, E_S_UNIT
, N_("Production Upgraded")),
167 GEN_EV(E_UNIT_RELOCATED
, E_S_UNIT
, N_("Relocated")),
168 GEN_EV(E_UNIT_ORDERS
, E_S_UNIT
, N_("Orders / goto events")),
169 GEN_EV(E_UNIT_BUILT_POP_COST
, E_S_UNIT
, N_("Built unit with population cost")),
170 /* TRANS: "vote" as a process */
171 GEN_EV(E_VOTE_NEW
, E_S_VOTE
, N_("New vote")),
172 /* TRANS: "Vote" as a process */
173 GEN_EV(E_VOTE_RESOLVED
, E_S_VOTE
, N_("Vote resolved")),
174 /* TRANS: "Vote" as a process */
175 GEN_EV(E_VOTE_ABORTED
, E_S_VOTE
, N_("Vote canceled")),
176 GEN_EV(E_WONDER_BUILD
, E_S_WONDER
, N_("Finished")),
177 GEN_EV(E_WONDER_OBSOLETE
, E_S_WONDER
, N_("Made Obsolete")),
178 GEN_EV(E_WONDER_STARTED
, E_S_WONDER
, N_("Started")),
179 GEN_EV(E_WONDER_STOPPED
, E_S_WONDER
, N_("Stopped")),
180 GEN_EV(E_WONDER_WILL_BE_BUILT
,E_S_WONDER
, N_("Will Finish Next Turn")),
181 GEN_EV(E_AI_DEBUG
, E_S_XYZZY
, N_("AI Debug messages")),
182 GEN_EV(E_BROADCAST_REPORT
, E_S_XYZZY
, N_("Broadcast Report")),
183 GEN_EV(E_CARAVAN_ACTION
, E_S_XYZZY
, N_("Caravan actions")),
184 GEN_EV(E_CHAT_ERROR
, E_S_XYZZY
, N_("Chat error messages")),
185 GEN_EV(E_CHAT_MSG
, E_S_XYZZY
, N_("Chat messages")),
186 GEN_EV(E_CONNECTION
, E_S_XYZZY
, N_("Connect/disconnect messages")),
187 GEN_EV(E_DIPLOMACY
, E_S_XYZZY
, N_("Diplomatic Message")),
188 GEN_EV(E_BAD_COMMAND
, E_S_XYZZY
, N_("Error message from bad command")),
189 GEN_EV(E_GAME_END
, E_S_XYZZY
, N_("Game Ended")),
190 GEN_EV(E_GAME_START
, E_S_XYZZY
, N_("Game Started")),
191 GEN_EV(E_NATION_SELECTED
, E_S_XYZZY
, N_("Nation Selected")),
192 GEN_EV(E_DESTROYED
, E_S_XYZZY
, N_("Player Destroyed")),
193 GEN_EV(E_REPORT
, E_S_XYZZY
, N_("Report")),
194 GEN_EV(E_LOG_FATAL
, E_S_XYZZY
, N_("Server Aborting")),
195 GEN_EV(E_LOG_ERROR
, E_S_XYZZY
, N_("Server Problems")),
196 GEN_EV(E_MESSAGE_WALL
, E_S_XYZZY
, N_("Message from server operator")),
197 GEN_EV(E_SETTING
, E_S_XYZZY
, N_("Server settings changed")),
198 GEN_EV(E_TURN_BELL
, E_S_XYZZY
, N_("Turn Bell")),
199 GEN_EV(E_SCRIPT
, E_S_XYZZY
, N_("Scenario/ruleset script message")),
200 /* TRANS: Event name for when the game year changes. */
201 GEN_EV(E_NEXT_YEAR
, E_S_XYZZY
, N_("Year Advance")),
202 /* The sound system also generates "e_game_quit", although there's no
203 * corresponding identifier E_GAME_QUIT. */
208 * Maps from enum event_type to indexes of events[]. Set by
211 static int event_to_index
[E_COUNT
];
213 enum event_type sorted_events
[E_COUNT
];
216 /**************************************************************************
217 Returns the translated description of the given event.
218 **************************************************************************/
219 const char *get_event_message_text(enum event_type event
)
221 fc_assert_ret_val(event_type_is_valid(event
), NULL
);
223 if (events
[event_to_index
[event
]].event
== event
) {
224 return events
[event_to_index
[event
]].full_descr
;
227 log_error("unknown event %d", event
);
228 return "UNKNOWN EVENT"; /* FIXME: Should be marked for translation?
229 * we get non-translated in log message. */
232 /**************************************************************************
233 Comparison function for qsort; i1 and i2 are pointers to an event
235 **************************************************************************/
236 static int compar_event_message_texts(const void *i1
, const void *i2
)
238 const enum event_type
*j1
= i1
;
239 const enum event_type
*j2
= i2
;
241 return fc_strcasecmp(get_event_message_text(*j1
),
242 get_event_message_text(*j2
));
245 /****************************************************************************
246 Returns a string for the sound to be used for this message type.
247 ****************************************************************************/
248 const char *get_event_sound_tag(enum event_type event
)
250 fc_assert_ret_val(event_type_is_valid(event
), NULL
);
252 if (events
[event_to_index
[event
]].event
== event
) {
253 return events
[event_to_index
[event
]].tag_name
;
255 log_error("unknown event %d", event
);
259 /****************************************************************************
260 If is_city_event is FALSE this event doesn't effect a city even if
261 there is a city at the event location.
262 ****************************************************************************/
263 bool is_city_event(enum event_type event
)
268 case E_UNIT_LOST_DEF
: /* FIXME: Is this correct.
269 * I'd like to find now defendeseless city quickly! */
270 case E_UNIT_LOST_MISC
:
272 case E_ENEMY_DIPLOMAT_FAILED
:
273 case E_ENEMY_DIPLOMAT_EMBASSY
:
274 case E_ENEMY_DIPLOMAT_POISON
:
275 case E_ENEMY_DIPLOMAT_BRIBE
:
276 case E_ENEMY_DIPLOMAT_INCITE
:
277 case E_ENEMY_DIPLOMAT_SABOTAGE
:
278 case E_ENEMY_DIPLOMAT_THEFT
:
279 case E_MY_DIPLOMAT_FAILED
:
280 case E_MY_DIPLOMAT_EMBASSY
:
281 case E_MY_DIPLOMAT_POISON
:
282 case E_MY_DIPLOMAT_BRIBE
:
283 case E_MY_DIPLOMAT_INCITE
:
284 case E_MY_DIPLOMAT_SABOTAGE
:
285 case E_MY_DIPLOMAT_THEFT
:
286 case E_MY_DIPLOMAT_ESCAPE
:
287 case E_UNIT_LOST_ATT
:
290 case E_UNIT_RELOCATED
:
298 /****************************************************************************
300 Now also initialise sorted_events[].
301 ****************************************************************************/
302 void events_init(void)
306 for (i
= 0; i
< ARRAY_SIZE(event_to_index
); i
++) {
307 event_to_index
[i
] = 0;
310 for (i
= 0; i
< E_COUNT
; i
++) {
313 if (E_S_XYZZY
> events
[i
].esn
) {
314 const char *event_format
= Q_(event_sections
[events
[i
].esn
]);
315 int l
= 1 + strlen(event_format
) + strlen(_(events
[i
].descr_orig
));
317 events
[i
].full_descr
= fc_malloc(l
);
318 fc_snprintf(events
[i
].full_descr
, l
, event_format
,
319 _(events
[i
].descr_orig
));
321 /* No section part */
322 events
[i
].full_descr
= _(events
[i
].descr_orig
);
325 event_to_index
[events
[i
].event
] = i
;
326 events
[i
].tag_name
= fc_strdup(events
[i
].enum_name
);
327 for (j
= 0; j
< strlen(events
[i
].tag_name
); j
++) {
328 events
[i
].tag_name
[j
] = fc_tolower(events
[i
].tag_name
[j
]);
330 log_debug("event[%d]=%d: name='%s' / '%s'\n"
331 "\tdescr_orig='%s'\n"
333 i
, events
[i
].event
, events
[i
].enum_name
, events
[i
].tag_name
,
334 events
[i
].descr_orig
, events
[i
].full_descr
);
337 for (i
= 0; i
<= event_type_max(); i
++) {
338 /* Initialise sorted list of all (even possble missing) events. */
339 sorted_events
[i
] = i
;
341 qsort(sorted_events
, event_type_max() + 1, sizeof(*sorted_events
),
342 compar_event_message_texts
);
345 /****************************************************************************
347 ****************************************************************************/
348 void events_free(void)
352 for (i
= 0; i
<= event_type_max(); i
++) {
353 if (E_S_XYZZY
> events
[i
].esn
) {
354 /* We have allocated memory for this event */
355 free(events
[i
].full_descr
);
356 events
[i
].full_descr
= NULL
;