Compare commits

9 Commits

Author SHA1 Message Date
Stan af4896b4c5 Set matchID at the start of a new match. Fix ratings being broken.
Refs: dc18d94030

Patch by: @user1
Discussed with: @bb
Reviewed by: @wraitii
This was SVN commit r25859.
2021-08-25 11:05:53 +00:00
Stan 84c2dc3f15 Add seagulls on top of fish to make them easier to spot.
This was SVN commit r25857.
2021-08-22 17:11:55 +00:00
Stan 54b832b6a6 Make big grass 25% smaller to improve visibility a bit on some maps. Ideally Random maps like wildlake would not put some next to the CCs.
This was SVN commit r25856.
2021-08-22 17:10:56 +00:00
Stan 26bfd92dbd Fix nopch build. broken in 52baaa4bbd.
This was SVN commit r25855.
2021-08-22 13:20:41 +00:00
Angen 52baaa4bbd Fix updating existing mods
Replace wrename, that fails when mod exists already with RenameFile by
@Stan
Check if mod was actually installed when downloading it
error if mod cannot be coppied into modTemp

Differential revision: D4222
This was SVN commit r25854.
2021-08-22 11:35:34 +00:00
Angen 83bb6f3ed5 Fix downloanded mods not showing in list until restart
since 498f0d420b
While at it, remove not used variable after 6400a4a0c5
also fix non visual replay broken in 6400a4a0c5

Differential revision: D4220
Tested by: @Stan, @Langbart
Fixes: #6288

This was SVN commit r25853.
2021-08-22 09:54:16 +00:00
Freagarach 2cf908a974 Fix game setup lobby player stats stanza.
Patch by: @nani
Differential revision: https://code.wildfiregames.com/D4213
Reviewed by: @Angen
This was SVN commit r25851.
2021-08-19 17:01:19 +00:00
Angen 6400a4a0c5 Update Available mods when installing them
Differential revision: D4211
Since 498f0d420b available mods where cached and not updated when new
where installed.
Fixing above.

This was SVN commit r25850.
2021-08-17 17:32:10 +00:00
Angen 8f5b5670ff Fix gui objects failing on undefined in modmod
Differential revision: D4209
Since some revision wraitii will probbaly know, I am not going to look
for it, guiobjects require exact data type so casting does not work when
it is not done beforehand.
Error reported by Stan.
Now installing pyromod should not trigger errors.

This was SVN commit r25849.
2021-08-17 17:29:54 +00:00
30 changed files with 176 additions and 68 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ function initGUIFilters()
function initGUIButtons(data)
{
// Either get back to the previous page or quit if there is no previous page
let hasPreviousPage = !data || data.cancelbutton;
let hasPreviousPage = !data || data.cancelbutton || false;
Engine.GetGUIObjectByName("cancelButton").hidden = !hasPreviousPage;
Engine.GetGUIObjectByName("quitButton").hidden = hasPreviousPage;
// Turn 'save' off, it will be enabled on any change.
@@ -8,12 +8,13 @@
<animation file="other/fish_generic_idle_b.dae" name="Idle" speed="50"/>
<animation file="other/fish_generic_idle_c.dae" name="Idle" speed="35"/>
</animations>
<props>
<prop actor="fauna/seagull_circle.xml" attachpoint="root"/>
</props>
<mesh>skeletal/fish_generic.dae</mesh>
</variant>
</group>
<group>
<variant frequency="100" name="generic texture">
<textures><texture file="skeletal/animal_fish_generic.png" name="baseTex"/></textures>
<textures>
<texture file="skeletal/animal_fish_generic.png" name="baseTex"/>
</textures>
</variant>
</group>
<material>basic_spec.xml</material>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<castshadow/>
<float/>
<group>
<variant name="Seagull" frequency="1">
<animations>
<animation file="other/seagull_flight.dae" name="Idle" speed="150"/>
</animations>
<textures>
<texture file="skeletal/animal_seagull.png" name="baseTex"/>
</textures>
<mesh>skeletal/seagull.dae</mesh>
</variant>
</group>
<material>default.xml</material>
</actor>
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<castshadow/>
<float/>
<group>
<variant frequency="100" name="fish mesh">
<animations>
<animation file="others/bird_circle_idle_01.dae" name="Idle" speed="100"/>
</animations>
<mesh>skeletal/bird_circle.dae</mesh>
<textures>
<texture file="null_white.dds" name="baseTex"/>
</textures>
</variant>
</group>
<group>
<variant frequency="100" name="Variant A">
<props>
<prop actor="fauna/seagull.xml" attachpoint="fish_01"/>
<prop actor="fauna/seagull.xml" attachpoint="fish_09"/>
<prop actor="fauna/seagull.xml" attachpoint="fish_19"/>
</props>
</variant>
<variant frequency="100" name="Variant B">
<props>
<prop actor="fauna/seagull.xml" attachpoint="fish_02"/>
<prop actor="fauna/seagull.xml" attachpoint="fish_10"/>
<prop actor="fauna/seagull.xml" attachpoint="fish_20"/>
</props>
</variant>
<variant frequency="100" name="Variant C">
<props>
<prop actor="fauna/seagull.xml" attachpoint="fish_05"/>
<prop actor="fauna/seagull.xml" attachpoint="fish_20"/>
</props>
</variant>
</group>
<material>default.xml</material>
</actor>
@@ -28,11 +28,8 @@
<prop actor="fauna/tuna.xml" attachpoint="fish_18"/>
<prop actor="fauna/tuna.xml" attachpoint="fish_19"/>
<prop actor="fauna/tuna.xml" attachpoint="fish_20"/>
<prop actor="fauna/seagull_circle.xml" attachpoint="root"/>
</props>
</variant>
</group>
<group>
<variant frequency="100" name="generic texture">
<textures>
<texture file="null_white.dds" name="baseTex"/>
</textures>
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<group>
<variant frequency="1" name="massive">
<variant frequency="1" name="Savanna Field Tall">
<mesh>gaia/grass_large_2_tall.dae</mesh>
</variant>
</group>
<group>
<variant frequency="1" name="texture">
<textures>
<texture file="gaia/grass_savanna_a.png" name="baseTex"/>
</textures>
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<group>
<variant frequency="1" name="massive">
<mesh>gaia/grass_steppe.dae</mesh>
</variant>
</group>
<group>
<variant frequency="1" name="texture">
<variant frequency="1" name="Steppe Field Tall">
<mesh>gaia/grass_large_2_tall.dae</mesh>
<textures>
<texture file="gaia/grass_steppe.png" name="baseTex"/>
</textures>
@@ -1,16 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<group>
<variant frequency="1" name="large">
<variant frequency="1" name="Tropic Field">
<mesh>gaia/grass_large_1.dae</mesh>
</variant>
<variant frequency="1" name="massive">
<mesh>gaia/grass_large_2.dae</mesh>
</variant>
</group>
<group>
<variant frequency="1" name="taxture">
<textures><texture file="gaia/grass_tropic_a.png" name="baseTex"/></textures>
<textures>
<texture file="gaia/grass_tropic_a.png" name="baseTex"/>
</textures>
</variant>
</group>
<material>basic_trans_wind.xml</material>
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
<group>
<variant frequency="1" name="massive">
<variant frequency="1" name="Tropic Field Tall">
<mesh>gaia/grass_large_2_tall.dae</mesh>
</variant>
</group>
<group>
<variant frequency="1" name="texture">
<textures>
<texture file="gaia/grass_tropic_a.png" name="baseTex"/>
</textures>
Binary file not shown.
@@ -2,7 +2,7 @@ GameSettings.prototype.Attributes.MatchID = class MatchID extends GameSetting
{
init()
{
this.matchID = Engine.GetMatchID();
this.matchID = 0;
}
toInitAttributes(attribs)
@@ -15,4 +15,9 @@ GameSettings.prototype.Attributes.MatchID = class MatchID extends GameSetting
if (attribs.matchID !== undefined)
this.matchID = attribs.matchID;
}
pickRandomItems()
{
this.matchID = Engine.GetMatchID();
}
};
@@ -126,7 +126,7 @@ class LobbyGameRegistrationController
{
let pData = { "Name": g_PlayerAssignments[guid].name };
if (g_PlayerAssignments[guid].player <= g_GameSettings.playerCount.nbPlayers)
if (g_PlayerAssignments[guid].player != -1)
++connectedPlayers;
else
pData.Team = "observer";
+18
View File
@@ -193,6 +193,24 @@ Status DeleteDirectory(const OsPath& path)
return INFO::OK;
}
Status RenameFile(const OsPath& path, const OsPath& newPath)
{
if (path.empty())
return INFO::OK;
try
{
fs::rename(path.string8(), newPath.string8());
}
catch (fs::filesystem_error& err)
{
debug_printf("RenameFile: failed to rename %s to %s.\n%s\n", path.string8().c_str(), path.string8().c_str(), err.what());
return ERR::EXCEPTION;
}
return INFO::OK;
}
Status CopyFile(const OsPath& path, const OsPath& newPath, bool override_if_exists/* = false*/)
{
+3 -1
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -88,4 +88,6 @@ LIB_API Status DeleteDirectory(const OsPath& dirPath);
LIB_API Status CopyFile(const OsPath& path, const OsPath& newPath, bool override_if_exists = false);
LIB_API Status RenameFile(const OsPath& path, const OsPath& newPath);
#endif // #ifndef INCLUDED_FILE_SYSTEM
+11 -1
View File
@@ -79,6 +79,7 @@ that of Atlas depending on commandline parameters.
#include "rlinterface/RLInterface.h"
#include "scriptinterface/ScriptContext.h"
#include "scriptinterface/ScriptEngine.h"
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/JSON.h"
#include "simulation2/Simulation2.h"
#include "simulation2/system/TurnManager.h"
@@ -192,6 +193,8 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
else
{
LOGMESSAGE("Installed mod %s", installer.GetInstalledMods().front());
ScriptInterface modInterface("Engine", "Mod", g_ScriptContext);
g_Mods.UpdateAvailableMods(modInterface);
RestartEngine();
}
break;
@@ -662,9 +665,16 @@ static void RunGameOrAtlas(int argc, const char* argv[])
// Install the mods without deleting the pyromod files
for (const OsPath& modPath : modsToInstall)
installer.Install(modPath, g_ScriptContext, true);
{
CModInstaller::ModInstallationResult result = installer.Install(modPath, g_ScriptContext, true);
if (result != CModInstaller::ModInstallationResult::SUCCESS)
LOGERROR("Failed to install '%s'", modPath.string8().c_str());
}
installedMods = installer.GetInstalledMods();
ScriptInterface modInterface("Engine", "Mod", g_ScriptContext);
g_Mods.UpdateAvailableMods(modInterface);
}
if (isNonVisual)
+2 -1
View File
@@ -866,6 +866,7 @@ bool Init(const CmdLineArgs& args, int flags)
if (flags & INIT_MODS)
{
ScriptInterface modInterface("Engine", "Mod", g_ScriptContext);
g_Mods.UpdateAvailableMods(modInterface);
std::vector<CStr> mods;
if (args.Has("mod"))
mods = args.GetMultiple("mod");
@@ -876,7 +877,7 @@ bool Init(const CmdLineArgs& args, int flags)
boost::split(mods, modsStr, boost::algorithm::is_space(), boost::token_compress_on);
}
if (!g_Mods.EnableMods(modInterface, mods, flags & INIT_MODS_PUBLIC))
if (!g_Mods.EnableMods(mods, flags & INIT_MODS_PUBLIC))
{
// In non-visual mode, fail entirely.
if (args.Has("autostart-nonvisual"))
+2 -3
View File
@@ -136,7 +136,7 @@ const std::vector<Mod::ModData>& Mod::GetAvailableMods() const
return m_AvailableMods;
}
bool Mod::EnableMods(const ScriptInterface& scriptInterface, const std::vector<CStr>& mods, const bool addPublic)
bool Mod::EnableMods(const std::vector<CStr>& mods, const bool addPublic)
{
m_IncompatibleMods.clear();
m_EnabledMods.clear();
@@ -156,8 +156,6 @@ bool Mod::EnableMods(const ScriptInterface& scriptInterface, const std::vector<C
if (counts["mod"] == 0)
m_EnabledMods.insert(m_EnabledMods.begin(), "mod");
UpdateAvailableMods(scriptInterface);
m_IncompatibleMods = CheckForIncompatibleMods(m_EnabledMods);
for (const CStr& mod : m_IncompatibleMods)
@@ -233,6 +231,7 @@ void Mod::UpdateAvailableMods(const ScriptInterface& scriptInterface)
{
PROFILE2("UpdateAvailableMods");
m_AvailableMods.clear();
const Paths paths(g_CmdLineArgs);
// loop over all possible paths
+11 -10
View File
@@ -56,13 +56,23 @@ public:
const std::vector<CStr>& GetIncompatibleMods() const;
const std::vector<ModData>& GetAvailableMods() const;
/**
* Fetches available mods and stores some metadata about them.
* This may open the zipped mod archives, depending on the situation,
* and/or try to write files to the user mod folder,
* which can be quite slow, so should be run rarely.
* TODO: if this did not need the scriptInterface to parse JSON,
* we could run it in different contexts and possibly cleaner.
*/
void UpdateAvailableMods(const ScriptInterface& scriptInterface);
/**
* Enables specified mods (& mods required by the engine).
* @param addPublic - if true, enable the public mod.
* @return whether the mods were enabled successfully. This can fail if e.g. mods are incompatible.
* If true, GetEnabledMods() should be non-empty, GetIncompatibleMods() empty. Otherwise, GetIncompatibleMods() is non-empty.
*/
bool EnableMods(const ScriptInterface& scriptInterface, const std::vector<CStr>& mods, const bool addPublic);
bool EnableMods(const std::vector<CStr>& mods, const bool addPublic);
/**
* Get data for the given mod.
@@ -83,15 +93,6 @@ public:
*/
static bool AreModsPlayCompatible(const std::vector<const Mod::ModData*>& modsA, const std::vector<const Mod::ModData*>& modsB);
private:
/**
* Fetches available mods and stores some metadata about them.
* This may open the zipped mod archives, depending on the situation,
* and/or try to write files to the user mod folder,
* which can be quite slow, so should be run rarely.
* TODO: if this did not need the scriptInterface to parse JSON,
* we could run it in different contexts and possibly cleaner.
*/
void UpdateAvailableMods(const ScriptInterface& scriptInterface);
/**
* Checks a list of @a mods and returns the incompatible mods, if any.
+19 -4
View File
@@ -20,6 +20,8 @@
#include "ModInstaller.h"
#include "lib/file/vfs/vfs_util.h"
#include "lib/file/file_system.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "ps/XML/Xeromyces.h"
#include "scriptinterface/ScriptInterface.h"
@@ -49,9 +51,18 @@ CModInstaller::ModInstallationResult CModInstaller::Install(
CreateDirectories(modTemp.Parent(), 0700);
if (keepFile)
CopyFile(mod, modTemp, true);
else
wrename(mod, modTemp);
{
if (CopyFile(mod, modTemp, true) != INFO::OK)
{
LOGERROR("Failed to copy '%s' to '%s'", mod.string8().c_str(), modTemp.string8().c_str());
return FAIL_ON_MOD_COPY;
}
}
else if (RenameFile(mod, modTemp) != INFO::OK)
{
LOGERROR("Failed to rename '%s' into '%s'", mod.string8().c_str(), modTemp.string8().c_str());
return FAIL_ON_MOD_MOVE;
}
// Load the mod to VFS
if (m_VFS->Mount(m_CacheDir, m_TempDir / "") != INFO::OK)
@@ -88,8 +99,12 @@ CModInstaller::ModInstallationResult CModInstaller::Install(
// mod-name.zip
// mod.json
CreateDirectories(modDir, 0700);
if (wrename(modTemp, modPath) != 0)
if (RenameFile(modTemp, modPath) != INFO::OK)
{
LOGERROR("Failed to rename '%s' into '%s'", modTemp.string8().c_str(), modPath.string8().c_str());
return FAIL_ON_MOD_MOVE;
}
DeleteDirectory(modTemp.Parent());
std::ofstream mod_json((modDir / "mod.json").string8());
+2 -1
View File
@@ -39,7 +39,8 @@ public:
FAIL_ON_PARSE_JSON,
FAIL_ON_EXTRACT_NAME,
FAIL_ON_MOD_MOVE,
FAIL_ON_JSON_WRITE
FAIL_ON_JSON_WRITE,
FAIL_ON_MOD_COPY
};
/**
+4 -1
View File
@@ -485,7 +485,10 @@ bool ModIo::AdvanceRequest(const ScriptInterface& scriptInterface)
{
Paths paths(g_CmdLineArgs);
CModInstaller installer(paths.UserData() / "mods", paths.Cache());
installer.Install(m_DownloadFilePath, g_ScriptContext, false);
CModInstaller::ModInstallationResult result = installer.Install(m_DownloadFilePath, g_ScriptContext, false);
if (result != CModInstaller::ModInstallationResult::SUCCESS)
LOGERROR("Failed to install '%s'", m_DownloadFilePath.string8().c_str());
g_Mods.UpdateAvailableMods(scriptInterface);
}
break;
default:
+2 -1
View File
@@ -233,7 +233,8 @@ void CReplayPlayer::Replay(const bool serializationtest, const int rejointesttur
mods.emplace_back(data.m_Pathname);
// Ignore the return value, we check below.
g_Mods.EnableMods(scriptInterface, mods, false);
g_Mods.UpdateAvailableMods(scriptInterface);
g_Mods.EnableMods(mods, false);
CheckReplayMods(replayMods);
MountMods(Paths(g_CmdLineArgs), g_Mods.GetEnabledMods());
+2 -2
View File
@@ -156,9 +156,9 @@ bool AreModsPlayCompatible(const std::vector<Mod::ModData>& a, const std::vector
return Mod::AreModsPlayCompatible(modsA, modsB);
}
bool SetModsAndRestartEngine(const ScriptInterface& scriptInterface, const std::vector<CStr>& mods)
bool SetModsAndRestartEngine(const std::vector<CStr>& mods)
{
if (!g_Mods.EnableMods(scriptInterface, mods, false))
if (!g_Mods.EnableMods(mods, false))
return false;
RestartEngine();