Compare commits

...

15 Commits

Author SHA1 Message Date
phosit a2cae4d69f Update appdata for next RC
(cherry picked from commit a2c59cf87f)
Signed-off-by: phosit <phosit@autistici.org>
2026-02-15 18:46:25 +01:00
Vladislav Belov 72c6aad939 Fixes Atlas Terrain panel in dark mode
(cherry picked from commit 70c15abadb)
Signed-off-by: phosit <phosit@autistici.org>
2026-02-15 18:46:25 +01:00
phosit a56ffcfd25 Update appdata for next RC
(cherry picked from commit 45c3a03a2e)
Signed-off-by: phosit <phosit@autistici.org>
2026-02-04 20:16:52 +01:00
real_tabasco_sauce 72e0ace313 German balance emergency changes
-Seeresses "Soldier" class removed as they are support units.
-Seeresses given correct vision value.
-Seeresses are unaffected by healer discount.
-germans no longer access archery spread tech since they have no archers.

(cherry picked from commit 87ed9c8092)
Signed-off-by: phosit <phosit@autistici.org>
2026-02-04 20:16:52 +01:00
Atrik 7033b81ce6 Default hotkeys changes
Reassign 'Toggle mouse grab' to F3 to avoid conflicts with gameplay hotkeys

Unassign 'Show status bars' often toggled by mistake by new players and confused for a selection bug

Assign 'Bird eye view' to Shift+Tab

(cherry picked from commit 426693ebef)
Signed-off-by: phosit <phosit@autistici.org>
2026-02-04 20:16:52 +01:00
phosit 30b741f8ba Update appdata for next RC
(cherry picked from commit 72591b7608)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:19 +01:00
Ralph Sennhauser 2da2c3394f Cleanly fail autostart for invalid map type
As for any invalid argument reject them and cleanly exit with failure
status.

Fixes: #7687
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
(cherry picked from commit 958e6de9d3)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:19 +01:00
Ralph Sennhauser f578a5b34d Readd JS API function Engine.Exit()
Requested in #8244 for scripting purposes and automated testing. Extend
the original design by adding a means to pass an exit status. This also
comes in handy in case one wants to cleanly error out from JS on parsing
errors of command line arguments as reported in #7967.

Fixes: #8244
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
(cherry picked from commit 0d60bdfd2e)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:19 +01:00
Vantha 8fee4dbb76 Temporary workaround for font baseline issue
Quick temporary fix for #8505 for the release of R28.

(cherry picked from commit 2483e7172b)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:19 +01:00
Vantha baa18fd57d Temporary workaround for icon misalignment
Quick temporary fix for #8194 for the release of R28.

(cherry picked from commit 7fd788af0f)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:19 +01:00
Atrik 231750edf1 Fix errors if promoted units change attack range
While in combat, if units are promoted and the promotion results
in a change in their attack range, this could trigger some errors
as 'this.template[type]' had a chance to be undefined when performing
a 'RepeatRangeCheck'.

Fixes #8670

(cherry picked from commit 68e625ab7a)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:18 +01:00
Ralph Sennhauser 0d1cdc0eaa Workaround renamed property in gamereport
The gendered citizen feature changed stat counter names in
3592814aa8 which are submitted to echelon
for rated games with the game report, the change in name for the property
means it no longer matches the database column name effectively breaking
rated games.

Translate the property name on the fly.

Fixes: #8687
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
(cherry picked from commit 0691e7f0ff)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-29 21:56:18 +01:00
phosit 63d4513ebf Serialize canPlay property in Petra
This was forgotten in 7b1d4426aa.

Fixes: #8674
(cherry picked from commit a6357322e9)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-22 20:43:57 +01:00
Dunedan a1cb3055d9 Fix string extraction of new game settings
5741f77c6e and b5256ce014 added new translatable strings for game
settings, but missed adding them to
binaries/data/mods/public/l10n/messages.json to get them properly
extracted into the PO-templates for translation. This commit fixes that.

(cherry picked from commit f4c52e49a7)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-15 18:06:48 +01:00
Dunedan 7fd034a2c0 Fix translatable strings in XML files
Some translatable strings in XML files have leading and trailing line
breaks and tabs. As these characters are significant in text in XML
files, they don't belong there.

Refs: #8649
(cherry picked from commit 8f8d1195c2)
Signed-off-by: phosit <phosit@autistici.org>
2026-01-14 20:59:47 +01:00
20 changed files with 97 additions and 47 deletions
+3 -3
View File
@@ -216,7 +216,7 @@ togglefullscreen = "Alt+Return" ; Toggle fullscreen/windowed mode
screenshot.watermark = "Alt+K" ; Toggle product/company watermark for official screenshots
wireframe = "Alt+Shift+W" ; Toggle wireframe mode
silhouettes = "Alt+Shift+S" ; Toggle unit silhouettes
mousegrabtoggle = "Ctrl+Alt" ; Toggle mouse grabbing mode
mousegrabtoggle = F3 ; Toggle mouse grabbing mode
; > DIALOG HOTKEYS
summary = "Ctrl+Tab" ; Toggle in-game summary
@@ -252,7 +252,7 @@ reset = "R" ; Reset camera rotation to default
follow = "" ; Follow the first unit in the selection
rallypointfocus = "" ; Focus the camera on the rally point of the selected building
lastattackfocus = "Space" ; Focus the camera on the last notified attack
togglebirdseyeview = "" ; Toggle bird's eye view
togglebirdseyeview = "Shift+Tab" ; Toggle bird's eye view
zoom.in = Plus, NumPlus ; Zoom camera in (continuous control)
zoom.out = Minus, NumMinus ; Zoom camera out (continuous control)
zoom.wheel.in = WheelUp ; Zoom camera in (stepped control)
@@ -392,7 +392,7 @@ flareactivate = "" ; Modifier to activate the mode to send a flare to
calltoarms = "" ; Modifier to call the selected units to the arms.
focusfire = "F" ; Modifier to control exclusively a building's arrows if it can attack
; Overlays
showstatusbars = Tab ; Toggle display of status bars
showstatusbars = "" ; Toggle display of status bars
devcommands.toggle = "Alt+D" ; Toggle developer commands panel
highlightguarding = PageDown ; Toggle highlight of guarding units
highlightguarded = PageUp ; Toggle highlight of guarded units
@@ -66,11 +66,20 @@ function parseCmdLineArgs(settings, cmdLineArgs)
{
// eslint-disable-next-line dot-notation
const mapType = cmdLineArgs['autostart'].substring(0, cmdLineArgs['autostart'].indexOf('/'));
settings.map.setType({
"scenarios": "scenario",
"random": "random",
"skirmishes": "skirmish",
}[mapType]);
switch (mapType)
{
case "random":
settings.map.setType("random");
break;
case "scenarios":
settings.map.setType("scenario");
break;
case "skirmishes":
settings.map.setType("skirmish");
break;
default:
throw new Error(`Unknown map type ${mapType}`);
}
// eslint-disable-next-line dot-notation
settings.map.selectMap("maps/" + cmdLineArgs['autostart']);
@@ -8,7 +8,5 @@
<translatableAttribute id="caption">Saved game</translatableAttribute>
<translatableAttribute id="tooltip">
The controller loaded a saved game.
</translatableAttribute>
<translatableAttribute id="tooltip">The controller loaded a saved game.</translatableAttribute>
</object>
@@ -1,7 +1,8 @@
/**
* Override style so we can get a bigger primary name.
*/
g_TooltipTextFormats.namePrimaryBig.font = "sans-bold-20";
// Temporarily overwritten in order to hide a baseline issue in the font engine.
g_TooltipTextFormats.namePrimaryBig.font = /* "sans-bold-20" */ "sans-bold-16";
g_TooltipTextFormats.namePrimarySmall.font = "sans-bold-16";
g_TooltipTextFormats.nameSecondary.font = "sans-bold-16";
@@ -23,25 +23,19 @@
<object>
<object name="icon1" type="image" sprite="stretched:pregame/icons/experimental.png"/>
<object name="text1" type="text" textcolor="white" font="sans-16">
<translatableAttribute id="caption">
This game is still in development. You may encounter bugs, and some features are not as fleshed out as we would like.
</translatableAttribute>
<translatableAttribute id="caption">This game is still in development. You may encounter bugs, and some features are not as fleshed out as we would like.</translatableAttribute>
</object>
</object>
<object>
<object name="icon2" type="image" sprite="stretched:pregame/icons/lag.png"/>
<object name="text2" type="text" textcolor="white" font="sans-16">
<translatableAttribute id="caption">
The game can have performance problems, especially with large maps and a great number of units.
</translatableAttribute>
<translatableAttribute id="caption">The game can have performance problems, especially with large maps and a great number of units.</translatableAttribute>
</object>
</object>
<object>
<object name="icon3" type="image" sprite="stretched:pregame/icons/map.png"/>
<object name="text3" type="text" textcolor="white" font="sans-16">
<translatableAttribute id="caption">
0 A.D. is Free Software: you can participate in its development. If you want to help with art, sound, gameplay or programming, make sure to join our official forum.
</translatableAttribute>
<translatableAttribute id="caption">0 A.D. is Free Software: you can participate in its development. If you want to help with art, sound, gameplay or programming, make sure to join our official forum.</translatableAttribute>
</object>
</object>
</object>
@@ -756,6 +756,32 @@
}
}
},
{
"extractor": "json",
"filemasks": [
"simulation/data/settings/player_placements.json"
],
"options": {
"keywords": {
"Name": {},
"Description": {}
}
}
},
{
"extractor": "json",
"filemasks": [
"simulation/data/settings/population_capacities.json"
],
"options": {
"keywords": {
"Title": {},
"Tooltip": {},
"CapTitle": {},
"CapTooltip": {}
}
}
},
{
"extractor": "json",
"filemasks": [
@@ -9,9 +9,9 @@ export function aiWarn(output)
/**
* Useful for simulating consecutive AI matches.
*/
export function exit()
export function exit(exitStatus)
{
Engine.Exit();
Engine.Exit(exitStatus);
}
export function VectorDistance(a, b)
@@ -31,6 +31,7 @@ PetraBot.prototype.CustomInit = function(gameState)
if (this.isDeserialized)
{
// WARNING: the deserializations should not modify the metadatas infos inside their init functions
this.canPlay = this.data.canPlay;
this.turn = this.data.turn;
this.playedTurn = this.data.playedTurn;
this.elapsedTime = this.data.elapsedTime;
@@ -151,6 +152,7 @@ PetraBot.prototype.Serialize = function()
}
return {
"canPlay": this.canPlay,
"uniqueIDs": this.uniqueIDs,
"turn": this.turn,
"playedTurn": this.playedTurn,
@@ -449,7 +449,7 @@ Attack.prototype.GetSplashData = function(type)
Attack.prototype.GetRange = function(type)
{
if (!type)
if (!type || !this.template[type])
return this.GetFullAttackRange();
let max = +this.template[type].MaxRange;
@@ -10,6 +10,7 @@
{ "tech": "phase_town" },
{ "notciv": "brit" },
{ "notciv": "gaul" },
{ "notciv": "germ" },
{ "notciv": "iber" },
{ "notciv": "rome" },
{ "notciv": "spart" }
@@ -15,6 +15,6 @@
{ "value": "Cost/Resources/metal", "replace": 0 },
{ "value": "Loot/metal", "replace": 0 }
],
"affects": ["Healer"],
"affects": ["Healer !Champion !Hero"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml"
}
@@ -25,7 +25,7 @@
</Health>
<Identity>
<GenericName>Champion Healer</GenericName>
<VisibleClasses datatype="tokens">Healer</VisibleClasses>
<VisibleClasses datatype="tokens">Healer -Soldier</VisibleClasses>
<Requirements>
<Techs datatype="tokens">phase_city</Techs>
</Requirements>
@@ -45,10 +45,13 @@
<Resistance>
<Entity>
<Damage>
<Hack>3</Hack>
<Pierce>3</Pierce>
<Hack>2</Hack>
<Pierce>4</Pierce>
<Crush>20</Crush>
</Damage>
</Entity>
</Resistance>
</Entity>
<Vision>
<Range>60</Range>
</Vision>
</Entity>
+2 -2
View File
@@ -40,8 +40,8 @@
<url type="translate">https://gitea.wildfiregames.com/0ad/0ad/wiki/Localization</url>
<url type="donation">https://play0ad.com/community/donate/</url>
<releases>
<release version="0.28.0" date="2026-01-05">
<url type="details">https://wildfiregames.com/forum/topic/137892-release-28-branch/</url>
<release version="0.28.0" date="2026-02-16">
<url type="details">https://play0ad.com/new-release-0-a-d-release-28-boiorix/</url>
<description>
<p>Wildfire Games proudly announces the release of 0 A.D. 0.28.0: "Boiorix".</p>
<ul>
+4 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -149,6 +149,9 @@ void CGUIString::GenerateTextCall(const CGUI& pGUI, SFeedback& Feedback, CStrInt
TextCall.m_Size = size;
SpriteCall.m_Area = size;
// Temporary workaround for a fundamental misalignment issue.
SpriteCall.m_Area += CSize2D{0.f, -3.f};
// Handle additional attributes
for (const TextChunk::Tag::TagAttribute& tagAttrib : tag.m_TagAttributes)
{
+11 -1
View File
@@ -394,11 +394,21 @@ void XmppClient::SendIqGameReport(const ScriptRequest& rq, JS::HandleValue data)
// Iterate through all the properties reported and add them to the stanza.
std::vector<std::string> properties;
Script::EnumeratePropertyNames(rq, data, true, properties);
// https://gitea.wildfiregames.com/0ad/0ad/issues/8687
const std::map<std::string, std::string> mappings{
{ "civilianUnitsLost", "femaleCitizenUnitsLost" },
{ "civilianUnitsTrained", "femaleCitizenUnitsTrained" },
{ "enemyCivilianUnitsKilled", "enemyFemaleCitizenUnitsKilled"}
};
for (const std::string& p : properties)
{
std::wstring value;
Script::GetProperty(rq, data, p.c_str(), value);
report->addAttribute(p, utf8_from_wstring(value));
if (mappings.contains(p))
report->addAttribute(mappings.at(p), utf8_from_wstring(value));
else
report->addAttribute(p, utf8_from_wstring(value));
}
// Add stanza to IQ
+8 -7
View File
@@ -166,6 +166,7 @@ enum ShutdownType
};
static ShutdownType g_Shutdown = ShutdownType::None;
static int g_ExitStatus{EXIT_SUCCESS};
// to avoid redundant and/or recursive resizing, we save the new
// size after VIDEORESIZE messages and only update the video mode
@@ -182,9 +183,10 @@ bool IsQuitRequested()
return g_Shutdown == ShutdownType::Quit;
}
void QuitEngine()
void QuitEngine(int exitStatus)
{
g_Shutdown = ShutdownType::Quit;
g_ExitStatus = exitStatus;
}
void RestartEngine()
@@ -210,7 +212,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
break;
case SDL_QUIT:
QuitEngine();
QuitEngine(EXIT_SUCCESS);
break;
case SDL_DROPFILE:
@@ -236,7 +238,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
if (hotkey == "exit")
{
QuitEngine();
QuitEngine(EXIT_SUCCESS);
return IN_HANDLED;
}
else if (hotkey == "screenshot")
@@ -506,7 +508,7 @@ static void NonVisualFrame()
g_Profiler.Frame();
if (g_Game->IsGameFinished())
QuitEngine();
QuitEngine(EXIT_SUCCESS);
}
static void MainControllerInit()
@@ -826,7 +828,6 @@ int main(int argc, char* argv[])
EarlyInit(); // must come at beginning of main
int returnValue{EXIT_SUCCESS};
try
{
// static_cast is ok, argc is never negative.
@@ -834,7 +835,7 @@ int main(int argc, char* argv[])
}
catch (const RL::SetupError&)
{
returnValue = EXIT_FAILURE;
g_ExitStatus = EXIT_FAILURE;
}
// Shut down profiler initialised by EarlyInit
@@ -848,5 +849,5 @@ int main(int argc, char* argv[])
wutil_Shutdown();
#endif
return returnValue;
return g_ExitStatus;
}
+4 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -47,6 +47,8 @@
class ScriptInterface;
extern void QuitEngine(int exitStatus);
namespace JSI_Main
{
bool AtlasIsAvailable()
@@ -134,6 +136,7 @@ std::string CalculateMD5(const std::string& input)
void RegisterScriptFunctions(const ScriptRequest& rq)
{
ScriptFunction::Register<&QuitEngine>(rq, "Exit");
ScriptFunction::Register<&AtlasIsAvailable>(rq, "AtlasIsAvailable");
ScriptFunction::Register<&IsAtlasRunning>(rq, "IsAtlasRunning");
ScriptFunction::Register<&OpenURL>(rq, "OpenURL");
+2 -2
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -25,7 +25,7 @@ bool IsQuitRequested()
return false;
}
void QuitEngine()
void QuitEngine(int)
{
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -87,7 +87,7 @@
#include <utility>
#include <vector>
extern void QuitEngine();
extern void QuitEngine(int exitStatus);
/**
* @file
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -344,7 +344,6 @@ public:
{
m_ScrolledPanel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_ScrolledPanel->SetScrollRate(0, 10);
m_ScrolledPanel->SetBackgroundColour(wxColor(255, 255, 255));
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_ScrolledPanel, wxSizerFlags().Proportion(1).Expand());