1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

- moved all system-specific handling of filesystem to VCMIDirs.cpp (new file)

- fixed #1128, artifact constituents are now stored as pointers
This commit is contained in:
Ivan Savenko 2013-03-02 18:41:25 +00:00
parent f306d7bb70
commit b5fcefe455
14 changed files with 173 additions and 142 deletions

View File

@ -155,9 +155,9 @@ void init()
static void prog_version(void)
{
printf("%s\n", GameConstants::VCMI_VERSION.c_str());
printf(" data directory: %s\n", GameConstants::DATA_DIR.c_str());
printf(" library directory: %s\n", GameConstants::LIB_DIR.c_str());
printf(" binary directory: %s\n", GameConstants::BIN_DIR.c_str());
printf(" data directory: %s\n", VCMIDirs::get().dataPath().c_str());
printf(" library directory: %s\n", VCMIDirs::get().libraryPath().c_str());
printf(" path to server: %s\n", VCMIDirs::get().serverPath().c_str());
}
static void prog_help(const po::options_description &opts)
@ -195,7 +195,7 @@ int main(int argc, char** argv)
OSX_checkForUpdates();
// Check that game data is prepared. Otherwise run vcmibuilder helper application
FILE* check = fopen((GVCMIDirs.UserPath + "/game_data_prepared").c_str(), "r");
FILE* check = fopen((VCMIDirs::get().localPath() + "/game_data_prepared").c_str(), "r");
if (check == NULL) {
system("open ./vcmibuilder.app");
return 0;
@ -253,7 +253,7 @@ int main(int argc, char** argv)
CStopWatch total, pomtime;
std::cout.flags(std::ios::unitbuf);
logfile = new std::ofstream((GVCMIDirs.UserPath + "/VCMI_Client_log.txt").c_str());
logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Client_log.txt").c_str());
console = new CConsoleHandler;
*console->cb = boost::bind(&processCommand, _1);
console->start();
@ -287,8 +287,8 @@ int main(int argc, char** argv)
{
tlog0 << "Fatal error: failed to load settings!\n";
tlog0 << "Possible reasons:\n";
tlog0 << "\tCorrupted local configuration file at " << GVCMIDirs.UserPath << "/config/settings.json\n";
tlog0 << "\tMissing or corrupted global configuration file at " << GameConstants::DATA_DIR << "/config/defaultSettings.json\n";
tlog0 << "\tCorrupted local configuration file at " << VCMIDirs::get().localPath() << "/config/settings.json\n";
tlog0 << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().dataPath() << "/config/defaultSettings.json\n";
tlog0 << "VCMI will now exit...\n";
exit(EXIT_FAILURE);
}

View File

@ -1590,7 +1590,7 @@ int CPlayerInterface::getLastIndex( std::string namePrefix)
using namespace boost::filesystem;
using namespace boost::algorithm;
path gamesDir = GVCMIDirs.UserPath + "/Games";
path gamesDir = VCMIDirs::get().localPath() + "/Games";
std::map<std::time_t, int> dates; //save number => datestamp
directory_iterator enddir;

View File

@ -763,8 +763,8 @@ CServerHandler::~CServerHandler()
void CServerHandler::callServer()
{
setThreadName("CServerHandler::callServer");
std::string logName = GVCMIDirs.UserPath + "/server_log.txt";
std::string comm = GameConstants::BIN_DIR + GameConstants::PATH_SEPARATOR + GameConstants::SERVER_NAME + " " + port + " > " + logName;
std::string logName = VCMIDirs::get().localPath() + "/server_log.txt";
std::string comm = VCMIDirs::get().serverPath() + " " + port + " > " + logName;
int result = std::system(comm.c_str());
if (result == 0)
tlog1 << "Server closed correctly\n";

View File

@ -359,26 +359,20 @@ void CArtHandler::loadArtifactJson(CArtifact * art, const JsonNode & artifact)
if (!artifact["components"].isNull())
{
art->constituents.reset(new std::vector<ArtifactID>());
art->constituents.reset(new std::vector<CArtifact *>());
BOOST_FOREACH (auto component, artifact["components"].Vector())
{
VLC->modh->identifiers.requestIdentifier("artifact." + component.String(), [art](si32 id)
VLC->modh->identifiers.requestIdentifier("artifact." + component.String(), [=](si32 id)
{
// when this code is called both combinational art as well as component are loaded
// so it is safe to access any of them
art->addConstituent(ArtifactID(id));
VLC->arth->artifacts[id]->constituentOf.push_back(art->id);
art->constituents->push_back(VLC->arth->artifacts[id]);
VLC->arth->artifacts[id]->constituentOf.push_back(art);
});
}
}
}
void CArtifact::addConstituent (ArtifactID component)
{
assert (constituents); // not a combinational art
constituents->push_back (component);
}
ArtifactID CArtHandler::creatureToMachineID(CreatureID id)
{
int dif = 142;
@ -745,15 +739,14 @@ std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CA
if(artType->constituents) //combined artifact already: no combining of combined artifacts... for now.
return ret;
BOOST_FOREACH(ui32 possibleCombinedArt, artType->constituentOf)
BOOST_FOREACH(const CArtifact * artifact, artType->constituentOf)
{
const CArtifact * const artifact = VLC->arth->artifacts[possibleCombinedArt];
assert(artifact->constituents);
bool possible = true;
BOOST_FOREACH(ui32 constituentID, *artifact->constituents) //check if all constituents are available
BOOST_FOREACH(const CArtifact * constituent, *artifact->constituents) //check if all constituents are available
{
if(!h->hasArt(constituentID, true)) //constituent must be equipped
if(!h->hasArt(constituent->id, true)) //constituent must be equipped
{
possible = false;
break;
@ -876,15 +869,15 @@ void CCombinedArtifactInstance::createConstituents()
assert(artType);
assert(artType->constituents);
BOOST_FOREACH(ui32 a, *artType->constituents)
BOOST_FOREACH(const CArtifact * art, *artType->constituents)
{
addAsConstituent(CArtifactInstance::createNewArtifactInstance(a), ArtifactPosition::PRE_FIRST);
addAsConstituent(CArtifactInstance::createNewArtifactInstance(art->id), ArtifactPosition::PRE_FIRST);
}
}
void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, ArtifactPosition slot)
{
assert(vstd::contains(*artType->constituents, art->artType->id));
assert(vstd::contains(*artType->constituents, art->artType.get()));
assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->artType);
constituentsInfo.push_back(ConstituentInfo(art, slot));
attachTo(art);

View File

@ -57,7 +57,6 @@ public:
const std::string &EventText() const;
bool isBig () const;
void addConstituent (ArtifactID component);
int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
std::string nodeName() const override;
@ -67,8 +66,8 @@ public:
ui32 price;
bmap<ArtBearer::ArtBearer, std::vector<ArtifactPosition> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
std::unique_ptr<std::vector<ArtifactID> > constituents; // Artifacts IDs a combined artifact consists of, or NULL.
std::vector<ArtifactID> constituentOf; // Reverse map of constituents - combined arts that include this art
std::unique_ptr<std::vector<CArtifact *> > constituents; // Artifacts IDs a combined artifact consists of, or NULL.
std::vector<CArtifact *> constituentOf; // Reverse map of constituents - combined arts that include this art
EartClass aClass;
ArtifactID id;

View File

@ -2,7 +2,7 @@
#include "CGameInterface.h"
#include "BattleState.h"
#include "GameConstants.h"
#include "VCMIDirs.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing
@ -72,26 +72,12 @@ rett * createAny(std::string dllname, std::string methodName)
return ret;
}
//Currently AI libraries use "lib" prefix only on non-win systems.
//May be applied to Win systems as well to remove this ifdef
#ifdef _WIN32
std::string getAIFileName(std::string input)
{
return input + '.' + GameConstants::LIB_EXT;
}
#else
std::string getAIFileName(std::string input)
{
return "lib" + input + '.' + GameConstants::LIB_EXT;
}
#endif
template<typename rett>
rett * createAnyAI(std::string dllname, std::string methodName)
{
tlog1<<"Opening "<<dllname<<"\n";
std::string filename = getAIFileName(dllname);
rett* ret = createAny<rett>(GameConstants::LIB_DIR + "/AI/" + filename, methodName);
std::string filename = VCMIDirs::get().libraryName(dllname);
rett* ret = createAny<rett>(VCMIDirs::get().libraryPath() + "/AI/" + filename, methodName);
ret->dllName = dllname;
return ret;
}

View File

@ -52,6 +52,7 @@ set(lib_SRCS
ResourceSet.cpp
RegisterTypes.cpp
VCMI_Lib.cpp
VCMIDirs.cpp
)
set(lib_HEADERS

View File

@ -321,16 +321,16 @@ void CResourceHandler::initialize()
initialLoader = new CResourceLoader;
resourceLoader = new CResourceLoader;
shared_ptr<ISimpleResourceLoader> rootDir(new CFilesystemLoader(GameConstants::DATA_DIR, 0, true));
shared_ptr<ISimpleResourceLoader> rootDir(new CFilesystemLoader(VCMIDirs::get().dataPath(), 0, true));
initialLoader->addLoader("GLOBAL/", rootDir, false);
initialLoader->addLoader("ALL/", rootDir, false);
auto userDir = rootDir;
//add local directory to "ALL" but only if it differs from root dir (true for linux)
if (GameConstants::DATA_DIR != GVCMIDirs.UserPath)
if (VCMIDirs::get().dataPath() != VCMIDirs::get().localPath())
{
userDir = shared_ptr<ISimpleResourceLoader>(new CFilesystemLoader(GVCMIDirs.UserPath, 0, true));
userDir = shared_ptr<ISimpleResourceLoader>(new CFilesystemLoader(VCMIDirs::get().localPath(), 0, true));
initialLoader->addLoader("ALL/", userDir, false);
}

View File

@ -16,46 +16,6 @@ namespace GameConstants
{
const std::string VCMI_VERSION = "VCMI 0.92";
/*
* DATA_DIR contains the game data (Data/, MP3/, ...).
* BIN_DIR is where the vcmiclient/vcmiserver binaries reside
* LIB_DIR is where the AI libraries reside (linux only)
*/
#if defined(_WIN32)
const std::string DATA_DIR = ".";
const std::string BIN_DIR = ".";
const std::string LIB_DIR = ".";
const std::string SERVER_NAME = "VCMI_server.exe";
const std::string LIB_EXT = "dll";
const std::string PATH_SEPARATOR = "\\";
#elif defined(__APPLE__)
const std::string DATA_DIR = "../Data";
const std::string BIN_DIR = ".";
const std::string LIB_DIR = ".";
const std::string SERVER_NAME = "./vcmiserver";
const std::string LIB_EXT = "dylib";
const std::string PATH_SEPARATOR = "/";
#else
#ifndef M_DATA_DIR
#error M_DATA_DIR undefined.
#else
const std::string DATA_DIR = M_DATA_DIR;
#endif
#ifndef M_BIN_DIR
#error M_BIN_DIR undefined.
#else
const std::string BIN_DIR = M_BIN_DIR;
#endif
#ifndef M_LIB_DIR
#error M_LIB_DIR undefined.
#else
const std::string LIB_DIR = M_LIB_DIR;
#endif
const std::string SERVER_NAME = "vcmiserver";
const std::string LIB_EXT = "so";
const std::string PATH_SEPARATOR = "/";
#endif
const int BFIELD_WIDTH = 17;
const int BFIELD_HEIGHT = 11;
const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
@ -73,13 +33,13 @@ namespace GameConstants
const ui16 BACKPACK_START = 19;
const int CREATURES_PER_TOWN = 7; //without upgrades
const int SPELL_LEVELS = 5;
const int CRE_LEVELS = 10; // number of creature experience levels
const int SPELLBOOK_GOLD_COST = 500;
const int BATTLE_PENALTY_DISTANCE = 10; //if the distance is > than this, then shooting stack has distance penalty
const int ARMY_SIZE = 7;
const int SKILL_PER_HERO=8;
const int CRE_LEVELS = 10;
const int SKILL_QUANTITY=28;
const int PRIMARY_SKILLS=4;
const int TERRAIN_TYPES=10;

View File

@ -829,9 +829,9 @@ DLL_LINKAGE void AssembledArtifact::applyGs( CGameState *gs )
CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
gs->map->addNewArtifactInstance(combinedArt);
//retrieve all constituents
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
BOOST_FOREACH(const CArtifact * constituent, *builtArt->constituents)
{
ArtifactPosition pos = artSet->getArtPos(constituentID);
ArtifactPosition pos = artSet->getArtPos(constituent->id);
assert(pos >= 0);
CArtifactInstance *constituentInstance = artSet->getArt(pos);

122
lib/VCMIDirs.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "StdInc.h"
#include "VCMIDirs.h"
/*
* VCMIDirs.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
static VCMIDirs VCMIDirsGlobal;
VCMIDirs::VCMIDirs()
{
// initialize local directory and create folders to which VCMI needs write access
boost::filesystem::create_directory(localPath());
boost::filesystem::create_directory(localPath() + "/config");
boost::filesystem::create_directory(localPath() + "/Games");
}
VCMIDirs & VCMIDirs::get()
{
return VCMIDirsGlobal;
}
//FIXME: find way to at least decrease size of this ifdef (along with cleanup in CMake)
#if defined(_WIN32)
std::string VCMIDirs::localPath() const
{
return dataPath();
}
std::string VCMIDirs::libraryPath() const
{
return dataPath();
}
std::string VCMIDirs::serverPath() const
{
return dataPath() + "\\" + "VCMI_server.exe";
}
std::string VCMIDirs::dataPath() const
{
return ".";
}
std::string VCMIDirs::libraryName(std::string basename) const
{
return basename + ".dll";
}
#elif defined(__APPLE__)
std::string VCMIDirs::localPath() const
{
// This is Cocoa code that should be normally used to get path to Application Support folder but can't use it here for now...
// NSArray* urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
// UserPath = path([urls[0] path] + "/vcmi").string();
// ...so here goes a bit of hardcode instead
std::string home_dir = ".";
if (getenv("HOME") != NULL )
home_dir = getenv("HOME");
return path(home_dir + "/Library/Application Support/vcmi").string();
}
std::string VCMIDirs::libraryPath() const
{
return ".";
}
std::string VCMIDirs::serverPath() const
{
return "./vcmiserver";
}
std::string VCMIDirs::dataPath() const
{
return "../Data";
}
std::string VCMIDirs::libraryName(std::string basename) const
{
return "lib" + basename + ".dylib";
}
#else
std::string VCMIDirs::localPath() const
{
if (getenv("HOME") != NULL )
return std::string(getenv("HOME")) + "/.vcmi";
return ".";
}
std::string VCMIDirs::libraryPath() const
{
return M_LIB_DIR;
}
std::string VCMIDirs::serverPath() const
{
return std::string(M_BIN_DIR) + "/" + "vcmiserver";
}
std::string VCMIDirs::dataPath() const
{
return M_DATA_DIR;
}
std::string VCMIDirs::libraryName(std::string basename) const
{
return "lib" + basename + ".so";
}
#endif

View File

@ -12,55 +12,27 @@
*
*/
#ifndef _WIN32 //we need boost here only on non-win platforms
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
#endif
/// Where to find the various VCMI files. This is mostly useful for linux.
class VCMIDirs {
class DLL_LINKAGE VCMIDirs
{
public:
std::string UserPath;
VCMIDirs();
VCMIDirs()
{
#ifdef _WIN32
UserPath = GameConstants::DATA_DIR;
#else
try {
#ifdef ANDROID
UserPath = DATA_DIR;
#elif defined(__APPLE__)
// This is Cocoa code that should be normally used to get path to Application Support folder but can't use it here for now...
// NSArray* urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
// UserPath = path([urls[0] path] + "/vcmi").string();
// ...so here goes a bit of hardcode instead
std::string home_dir = ".";
if (getenv("HOME") != NULL )
home_dir = getenv("HOME");
UserPath = path(home_dir + "/Library/Application Support/vcmi").string();
#else
// Find vcmi user directory and create it if necessary
std::string home_dir = ".";
if (getenv("HOME") != NULL )
home_dir = getenv("HOME");
/// get singleton instance
static VCMIDirs & get();
UserPath = path(home_dir + "/.vcmi").string();
#endif
create_directory(UserPath);
create_directory(UserPath + "/config");
create_directory(UserPath + "/Games");
/// Path to local, user-specific directory (e.g. ~/.vcmi on *nix systems)
std::string localPath() const;
/* Home directory can contain some extra maps. */
create_directory(UserPath + "/Maps");
}
catch(const std::exception & e)
{
}
#endif
}
/// Path where vcmi libraries can be found (in AI and Scripting subdirectories)
std::string libraryPath() const;
/// Path to vcmiserver, including server name (e.g. /usr/bin/vcmiserver)
std::string serverPath() const;
/// Path to global system-wide data directory
std::string dataPath() const;
/// Returns system-specific name for dynamic libraries ("libStupidAI.so" or "StupidAI.dll")
std::string libraryName(std::string basename) const;
};
extern DLL_LINKAGE VCMIDirs GVCMIDirs;

View File

@ -29,8 +29,6 @@
LibClasses * VLC = NULL;
DLL_LINKAGE VCMIDirs GVCMIDirs;
DLL_LINKAGE void preinitDLL(CConsoleHandler *Console, std::ostream *Logfile)
{
console = Console;

View File

@ -505,7 +505,7 @@ int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char** argv)
#endif
{
logfile = new std::ofstream((GVCMIDirs.UserPath + "/VCMI_Server_log.txt").c_str());
logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Server_log.txt").c_str());
console = new CConsoleHandler;
//boost::thread t(boost::bind(&CConsoleHandler::run,::console));
if(argc > 1)