diff --git a/3rd_party/oxygine-framework/oxygine/res/ResAtlasGeneric.cpp b/3rd_party/oxygine-framework/oxygine/res/ResAtlasGeneric.cpp index ea7fef387..3e1a77698 100644 --- a/3rd_party/oxygine-framework/oxygine/res/ResAtlasGeneric.cpp +++ b/3rd_party/oxygine-framework/oxygine/res/ResAtlasGeneric.cpp @@ -7,6 +7,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/settings.h" +#include "coreengine/virtualpaths.h" namespace oxygine { @@ -65,13 +66,10 @@ namespace oxygine qint32 columns = 0; qint32 rows = 0; QImage img; - if (QFile::exists(Settings::getInstance()->getUserPath() + walker.getPath("file"))) + QString imgFilePath = VirtualPaths::find(walker.getPath("file")); + if (QFile::exists(imgFilePath)) { - img = QImage(Settings::getInstance()->getUserPath() + walker.getPath("file")); - } - else if (QFile::exists(RCC_PREFIX_PATH + walker.getPath("file"))) - { - img = QImage(RCC_PREFIX_PATH + walker.getPath("file")); + img = QImage(imgFilePath); } else { diff --git a/3rd_party/oxygine-framework/oxygine/res/Resources.cpp b/3rd_party/oxygine-framework/oxygine/res/Resources.cpp index ccbe4a5a9..493701e54 100644 --- a/3rd_party/oxygine-framework/oxygine/res/Resources.cpp +++ b/3rd_party/oxygine-framework/oxygine/res/Resources.cpp @@ -113,7 +113,7 @@ namespace oxygine if (!file.exists() || file.size() == 0) { CONSOLE_PRINT_MODULE("can't load xml file: '" + xmlFile + "'", GameConsole::eDEBUG, GameConsole::eResources); - oxygine::handleErrorPolicy(oxygine::ep_show_error, "Resources::loadXML can't find xml file"); + oxygine::handleErrorPolicy(oxygine::ep_show_error, "Resources::loadXML can't find xml file: " + xmlFile); return false; } file.open(QIODevice::ReadOnly); diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ae81cb62..978bf032e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,6 +636,7 @@ set(${PROJECT_NAME}_SRCS coreengine/gameversion.h coreengine/gameversion.cpp coreengine/refobject.h coreengine/jsthis.h coreengine/jsthis.cpp + coreengine/virtualpaths.h coreengine/virtualpaths.cpp # network engine network/smtpmailsender.h network/smtpmailsender.cpp @@ -955,7 +956,8 @@ if (NOT DEPLOY_RESOURCES_AS_FOLDER) ) endif() else() - message("Deploying resources") + message("Deploying resources as folder") + add_definitions(-DDEPLOY_RESOURCES_AS_FOLDER) endif() qt_add_resources(${PROJECT_NAME}_Resource_SRCS "core.qrc") # These files are always deployed using QRCs. @@ -1045,6 +1047,7 @@ set(AppHeadersCxx coreengine/scriptvariables.h coreengine/settings.h coreengine/userdata.h + coreengine/virtualpaths.h game/building.h game/co.h game/gameaction.h @@ -1345,7 +1348,8 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "." BUNDLE DESTINATION "." - LIBRARY DESTINATION ".") + LIBRARY DESTINATION "." + ) install(DIRECTORY templates DESTINATION "/") if (DEPLOY_RESOURCES_AS_FOLDER) @@ -1375,7 +1379,18 @@ elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "bin" BUNDLE DESTINATION "bin" - LIBRARY DESTINATION "bin") + LIBRARY DESTINATION "bin" + ) + + if (DEPLOY_RESOURCES_AS_FOLDER) + message("Installing resources as folder") + install(DIRECTORY resources DESTINATION "share/commander_wars") + install(DIRECTORY maps DESTINATION "share/commander_wars") + install(DIRECTORY customTerrainImages DESTINATION "share/commander_wars") + install(DIRECTORY mods DESTINATION "share/commander_wars") + install(DIRECTORY savegames DESTINATION "share/commander_wars") + install(DIRECTORY data DESTINATION "share/commander_wars") + endif() elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android") if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/android-build/build/outputs/apk/debug/android-build-debug.apk" diff --git a/ai/coreai.cpp b/ai/coreai.cpp index 477800b8a..ce25608d9 100644 --- a/ai/coreai.cpp +++ b/ai/coreai.cpp @@ -14,6 +14,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/globalutils.h" +#include "coreengine/virtualpaths.h" #include "resource_management/cospritemanager.h" #include "resource_management/weaponmanager.h" @@ -163,27 +164,20 @@ TargetedUnitPathFindingSystem* CoreAI::createTargetedPfs(Unit* pUnit, const QVec void CoreAI::loadIni(QString file) { - AI_CONSOLE_PRINT("CoreAI::loadIni " + file, GameConsole::eDEBUG); - m_iniFiles.append(file); - QStringList searchFiles; - if (!file.isEmpty()) - { - searchFiles.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/aidata/" + file); - searchFiles.append(Settings::getInstance()->getUserPath() + "resources/aidata/" + file); - // make sure to overwrite existing js stuff - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchFiles.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + "/aidata/" + file); - searchFiles.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/aidata/" + file); - } - } - for (auto & file : searchFiles) + AI_CONSOLE_PRINT("CoreAI::loadIni " + file, GameConsole::eDEBUG); + m_iniFiles.append(file); + if (file.isEmpty()) + { + return; + } + QStringList searchFiles = VirtualPaths::findAll("resources/aidata/" + file); + for (auto & file : searchFiles) + { + if (QFile::exists(file)) { - if (QFile::exists(file)) - { - readIni(file); - } + readIni(file); } + } } void CoreAI::readIni(QString name) diff --git a/awbwReplayReader/awbwreplaydownloader.h b/awbwReplayReader/awbwreplaydownloader.h index 3e1eba880..e5d715522 100644 --- a/awbwReplayReader/awbwreplaydownloader.h +++ b/awbwReplayReader/awbwreplaydownloader.h @@ -5,11 +5,13 @@ #include #include +#include "coreengine/settings.h" + class AwbwReplayDownloader : public QObject { Q_OBJECT public: - explicit AwbwReplayDownloader(const QString & downloadPath = "data/records/", QObject *parent = nullptr); + explicit AwbwReplayDownloader(const QString & downloadPath = Settings::getInstance()->getUserPath() + "data/records/", QObject *parent = nullptr); void login(const QString & userName, const QString & password); void downLoadReplay(const QString & userName, const QString & password, const QString replay); diff --git a/core.qrc b/core.qrc index db3898e82..db9fbc5b7 100644 --- a/core.qrc +++ b/core.qrc @@ -4,5 +4,6 @@ system/frac_table_shader.glsl system/frac_matrix_shader.glsl system/vertex_shader.glsl + system/startup_messages.txt diff --git a/coreengine/audiomanager.cpp b/coreengine/audiomanager.cpp index 7737b1d77..e48067beb 100644 --- a/coreengine/audiomanager.cpp +++ b/coreengine/audiomanager.cpp @@ -4,6 +4,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/interpreter.h" #include "coreengine/globalutils.h" +#include "coreengine/virtualpaths.h" #include #include @@ -133,17 +134,9 @@ void AudioManager::createSoundCache() { if (Mainapp::getInstance()->isAudioThread()) { - QStringList searchFolders; - searchFolders.append(Settings::getInstance()->getUserPath() + "resources/sounds/"); - searchFolders.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/sounds/"); - QStringList mods = Settings::getInstance()->getMods(); - for (const auto & mod : std::as_const(mods)) + auto searchPath = VirtualPaths::createSearchPathRev("resources/sounds/"); + for (auto & folder : searchPath) { - searchFolders.append(Settings::getInstance()->getUserPath() + mod + "/sounds/"); - } - for (qint32 i = searchFolders.size() - 1; i >= 0; --i) - { - QString folder = searchFolders[i]; if (QFile::exists(folder + "res.xml")) { readSoundCacheFromXml(folder); @@ -165,7 +158,6 @@ void AudioManager::createSoundCache() else { emit sigCreateSoundCache(); - } } #endif @@ -560,17 +552,7 @@ bool AudioManager::tryAddMusic(QString file, qint64 startPointMs, qint64 endPoin #ifdef AUDIOSUPPORT if (!m_noAudio) { - QString currentPath = file; - currentPath = file; - if (!QFile::exists(currentPath)) - { - currentPath = Settings::getInstance()->getUserPath() + file; - if (!QFile::exists(currentPath)) - { - CONSOLE_PRINT_MODULE("Unable to locate music file: " + currentPath + " using compiled path.", GameConsole::eDEBUG, GameConsole::eAudio); - currentPath = oxygine::Resource::RCC_PREFIX_PATH + file; - } - } + QString currentPath = VirtualPaths::find(file); if (QFile::exists(currentPath)) { m_player->m_player.stop(); @@ -651,15 +633,10 @@ void AudioManager::SlotLoadFolder(QString folder) { #ifdef AUDIOSUPPORT QStringList loadedSounds; - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - loadMusicFolder(Settings::getInstance()->getUserPath() + "/" + Settings::getInstance()->getMods().at(i) + "/" + folder, loadedSounds); - loadMusicFolder(QString(oxygine::Resource::RCC_PREFIX_PATH) + "/" + Settings::getInstance()->getMods().at(i) + "/" + folder, loadedSounds); - } - if (m_loadBaseGameFolders) + QStringList searchPath = VirtualPaths::createSearchPathRev(folder); + for (QString folder : searchPath) { - loadMusicFolder(Settings::getInstance()->getUserPath() + folder, loadedSounds); - loadMusicFolder(oxygine::Resource::RCC_PREFIX_PATH + folder, loadedSounds); + loadMusicFolder(folder, loadedSounds); } #endif } diff --git a/coreengine/filesupport.h b/coreengine/filesupport.h index 1bb8fbb27..eef65ad72 100644 --- a/coreengine/filesupport.h +++ b/coreengine/filesupport.h @@ -1,6 +1,7 @@ #ifndef FILESUPPORT_H #define FILESUPPORT_H +#include #include #include #include @@ -134,4 +135,4 @@ class Filesupport final } }; -#endif // HASHING_H +#endif // FILESUPPORT_H diff --git a/coreengine/gameconsole.cpp b/coreengine/gameconsole.cpp index a10eba7cd..44581f5e7 100644 --- a/coreengine/gameconsole.cpp +++ b/coreengine/gameconsole.cpp @@ -496,1024 +496,42 @@ void GameConsole::resetMapsGameRules(const QString & folder) } } -void GameConsole::createfunnymessage(qint32 message){ +static const QStringList& getFunnyMessages() { + static QStringList list; + bool finished = false; + if (!finished) + { + QFile inputFile(":/system/startup_messages.txt"); + if (inputFile.open(QIODevice::ReadOnly)) + { + QTextStream in(&inputFile); + while (!in.atEnd()) + { + QString line = in.readLine(); + if (!line.isEmpty()) + { + list.append(line); + } + } + inputFile.close(); + } + + finished = true; + } + return list; +} + +void GameConsole::createfunnymessage(qint32 message) { + const QStringList& messages = getFunnyMessages(); if (message < 0) { - message = GlobalUtils::randIntBase(0,337); + message = GlobalUtils::randIntBase(0, messages.length()); } - QString printmessage; - switch(message) + + QString printmessage = "No more funny Messages found. Delete your Harddisk instead"; + if (message < messages.length()) { - case 0: - printmessage = "No funny games found :( -> Installing some funny Viruses!"; - break; - case 1: - printmessage = "Remember Bug 1#: The calculation is correct, but why the hell is the output wrong? Maybe the Input is wrong... Maybe"; - break; - case 2: - printmessage = "What? I should work faster? Look at your PC even a snake is faster than your CPU"; - break; - case 3: - printmessage = "I know this Quest. Nothing can happen! Sorry we could not find their corps!"; - break; - case 4: - printmessage = "1+1=10 ... What you don't understand Binary Stuff -> I can't work with such stupid Users."; - break; - case 5: - printmessage = "No good music found. No good videos found. There's nothing funny i can do here."; - break; - case 6: - printmessage = "Even if you're eaten by a dragon, you still have two ways out."; - break; - case 7: - printmessage = "I know what you did last summer..."; - break; - case 8: - printmessage = "Positioning GPS satellites... please stand by..."; - break; - case 9: - printmessage = "The volume goes to eleven!"; - break; - case 10: - printmessage = "The game will start when it is ready and not before!"; - break; - case 11: - printmessage = "You are the weakest link, goodbye!"; - break; - case 12: - printmessage = "/* You are not expected to understand this */"; - break; - case 13: - printmessage = "Computer load this, computer load that, never a thank you... Rude gamers!"; - break; - case 14: - printmessage = "Now that's what I call a dead parrot"; - break; - case 15: - printmessage = "Loading errors, please wait..."; - break; - case 16: - printmessage = "Your soundcard sucks, disabling sound forever..."; - break; - case 17: - printmessage = "Relax, it's only ones and zeros!"; - break; - case 18: - printmessage = "No, this is not a silly message."; - break; - case 19: - printmessage = "I still know what you did last summer..."; - break; - case 20: - printmessage = "Please stand by for an important announcement."; - break; - case 21: - printmessage = "Your computer is running... You better go chase it."; - break; - case 22: - printmessage = "Drawing beards onto your photographs..."; - break; - case 23: - printmessage = "Did you know that by reading this message you have wasted 5 seconds of your life?"; - break; - case 24: - printmessage = "Press any key... No! Not that one!"; - break; - case 25: - printmessage = "PI is exactly 3! Because I want to find out how world looks like where PI is exactly 3!"; - break; - case 26: - printmessage = "Freedom for wolves, ban the shepherds!"; - break; - case 27: - printmessage = "Your computer is now an official part of my world domination plan. Thank you!"; - break; - case 28: - printmessage = "There's nothing to see here, go ahead..."; - break; - case 29: - printmessage = "I don't care what you did last summer!"; - break; - case 30: - printmessage = "Ohh... I am loading too slowly? Ok, next time you'll load it yourself!"; - break; - case 31: - printmessage = "Searching for available information on dragons - Connecting to Wikipedia..."; - break; - case 32: - printmessage = "Warning: Don't try this at home! Why do you ignore this warning?"; - break; - case 33: - printmessage = "Are we there yet? Are we there yet? Are we there yet? "; - break; - case 34: - printmessage = "Oh this game sucks. It really game sucks! Did you know this game sucks!"; - break; - case 35: - printmessage = "Infiltrated your computer continuing to send your special videos to the CIA! Please Wait!"; - break; - case 36: - printmessage = "Press Any Key. I can't find the Any Key."; - break; - case 37: - printmessage = "Why is it forbidden to use Emergency Exits in Germany? I mean they are called ""Not Exit"""; - break; - case 38: - printmessage = "Let's play tic-tac-toe instead, I'll be X..."; - break; - case 39: - printmessage = "Coffee missing. Insert cup and press any key."; - break; - case 40: - printmessage = "Clicking the mouse will not make the game load faster!"; - break; - case 41: - printmessage = "Knowledge is a weapon... I intend to be formidably armed."; - break; - case 42: - printmessage = " I can't get no... Bug infection..."; - break; - case 43: - printmessage = "Press Crtl + Alt + Del now for an IQ test. Sorry IQ is to low to press those Keys."; - break; - case 44: - printmessage = "Press any key to continue or other key to quit..."; - break; - case 45: - printmessage = "You did not call in sick just to play this game, now did you?"; - break; - case 46: - printmessage = "Backup not found: (A)bort, (R)etry, (G)et a beer. "; - break; - case 47: - printmessage = "Nuclear Power Plants are save as long as you don't try to use them to produce energy!"; - break; - case 48: - printmessage = "Your computer is your friend....Trust the Computer..."; - break; - case 49: - printmessage = "Counting to Infinity......Please wait..."; - break; - case 50: - printmessage = "This is not a drill. This is the Apocalypse. Please stay calm and exit the building."; - break; - case 51: - printmessage = "Does a Table disappear always you leave a room. Because the modern physic says: it's possible!"; - break; - case 52: - printmessage = "Its not a bug but a feature."; - break; - case 53: - printmessage = "Life? Don't talk to me about life!"; - break; - case 54: - printmessage = "Does a Table disappear always you leave a room. Because the modern physic says: it's possible!"; - break; - case 55: - printmessage = "Its not a bug but a feature."; - break; - case 56: - printmessage = "Life? Don't talk to me about life!"; - break; - case 57: - printmessage = "Stop staring at this message or I will stop loading!"; - break; - case 58: - printmessage = "Loading 3D buffer... Not that one!"; - break; - case 59: - printmessage = "I've calculated your chance of survival, but I don't think you'll like it."; - break; - case 60: - printmessage = "No more heroes available. Do you want to play as a monster? (Y/N)"; - break; - case 61: - printmessage = "Is their any sense in killing all those monsters? I mean the time you are back. They're back, too"; - break; - case 62: - printmessage = "Do you really want to start the game? Really? Are you really sure?"; - break; - case 63: - printmessage = "Gaming is about killing time, not killing people..."; - break; - case 64: - printmessage = "Ordering pizza online... I hope you like anchovies with pineapple!"; - break; - case 65: - printmessage = "Insert Disc 5... Oh, you don't have a Disc 5? Ok, filling harddisc with garbage..."; - break; - case 66: - printmessage = "Wasting energy, please wait..."; - break; - case 67: - printmessage = "Overclocking CPU: 3,0GHz...3,2GHz...3,6GHz... OOPS, I broke your CPU!"; - break; - case 68: - printmessage = "There is a light at the end of the tunnel, just pray it's not a train."; - break; - case 69: - printmessage = "Please do not feed the dragons!"; - break; - case 70: - printmessage = "Not now! Can't you see I'm busy? Play something else."; - break; - case 71: - printmessage = "Would you like to play a game of... world domination?"; - break; - case 72: - printmessage = "Insert coin to continue..."; - break; - case 73: - printmessage = "How can this task be delayed when i haven't even started working on it?"; - break; - case 74: - printmessage = "If the game does not start in five minutes... wait longer!"; - break; - case 75: - printmessage = "Randomizing constants..."; - break; - case 76: - printmessage = "Scroll down the list and choose your favourite silly message. I'm too lazy."; - break; - case 77: - printmessage = "There's something written about a chance but I don't trust this game..."; - break; - case 78: - printmessage = "Checking mouse driver... Checking mouse's driving license..."; - break; - case 79: - printmessage = "Generating dead undead... Undead dead... uh..."; - break; - case 80: - printmessage = "Your skill in reading is increased by one point!"; - break; - case 81: - printmessage = "You'll get an adventure poqint32 for reading so much stupid messages. Use this poqint32 for improving your Stupidness!"; - break; - case 82: - printmessage = "Save the Earth... its the only planet with chocolate!"; - break; - case 83: - printmessage = "Why should we save the world? We didn't find out if we can survive without the world!"; - break; - case 84: - printmessage = "Operation failed (A)bort, (R)etry, (I)nfluence with large hammer?"; - break; - case 85: - printmessage = "The past temps us, the present confuses us, and the future frightens us."; - break; - case 86: - printmessage = "Checking co2 emissions of your computer... Sorry, it's to high turning off your PC."; - break; - case 87: - printmessage = "Are you still in the loading screen? You need a new computer!"; - break; - case 88: - printmessage = "Deleting all other games on the computer... You'll not need them in the next 5 seconds."; - break; - case 89: - printmessage = "How long can you withstand dragon breath again?"; - break; - case 90: - printmessage = "Do you want to continue? (Y)es, (N)o, (M)aybe"; - break; - case 91: - printmessage = "Incredible... it's even worse than i thought it would be."; - break; - case 92: - printmessage = "It seems that your mouse pointer is trying to move, (C)ancel or (A)llow?"; - break; - case 93: - printmessage = "Mommy, there's a monster in front of my screen!"; - break; - case 94: - printmessage = "Load it yourself, you slave driver!"; - break; - case 95: - printmessage = "You look rather silly staring at this screen..."; - break; - case 96: - printmessage = "Call 911 for support... "; - break; - case 97: - printmessage = "****, can't find this silly message file..."; - break; - case 98: - printmessage = "Are you sure you can still see the real world as real world?"; - break; - case 99: - printmessage = "Warning! your computer will self destruct in 5... 4... 3... 2... 1... "; - break; - case 100: - printmessage = "Don't you have better things to do then reading silly messages?"; - break; - case 101: - printmessage = "Who wants to live forever? Well... I wouldn't mind giving it a try!"; - break; - case 102: - printmessage = "Understanding is a three edged sword... our side, their side and the truth!"; - break; - case 103: - printmessage = "You're part of the game now..."; - break; - case 104: - printmessage = "There's a fine line between genius and insanity. I have erased this line."; - break; - case 105: - printmessage = "ealth warning: you have been playing for 12 seconds..."; - break; - case 106: - printmessage = "Keep clicking until i say stop!"; - break; - case 107: - printmessage = "Two beer or not two beer..."; - break; - case 108: - printmessage = "If you have a slow pc, you are able to learn every silly message by heart..."; - break; - case 109: - printmessage = "Failed to load quests, I will now try to create some on my own..."; - break; - case 110: - printmessage = "Starting your mp3s... Argh, i can't listen to this anymore, go get some new songs!"; - break; - case 111: - printmessage = "Press y+m+q+enter+space with one hand to continue."; - break; - case 112: - printmessage = "We don't have bugs, we have dragons!"; - break; - case 114: - printmessage = "This message is intended not to be funny."; - break; - case 113: - printmessage = "I don't know what you're talking about, there is no game here..."; - break; - case 115: - printmessage = "I invented the 'hello world' program!"; - break; - case 116: - printmessage = "CPU says you should not start those boring office programs anymore."; - break; - case 117: - printmessage = "What do you think I am doing? Loading the game?"; - break; - case 118: - printmessage = "Let's ride some trojan horses... I've found two in the left corner of your harddisc."; - break; - case 119: - printmessage = "Killing some bugs, please wait..."; - break; - case 120: - printmessage = "Loading loadingscreen..."; - break; - case 121: - printmessage = "Hit any user to continue."; - break; - case 122: - printmessage = "This game never has bugs. It just develops random features!"; - break; - case 123: - printmessage = "You just can't trust developers these days - they got even the silly messages bugged!"; - break; - case 124: - printmessage = "I don't have a solution, but I admire the problem!"; - break; - case 125: - printmessage = "There cannot be a crisis today, my schedule is already full."; - break; - case 126: - printmessage = "I have a fix opinion, don't confuse me with facts!"; - break; - case 127: - printmessage = "The best way to create panic is to say: There is no reason to react panically."; - break; - case 128: - printmessage = "If you want to continue roll a dice with excatly 21 numbers."; - break; - case 129: - printmessage = "Did you feed your Mouse? Because i think it's dead!"; - break; - case 130: - printmessage = "If a chance to survive is excactly 1:1000000. Than you'll survive to 100%. Tell me if i'm right by finding it out!"; - break; - case 131: - printmessage = "I prefer a Sword instead of the well known Weapon Knowledge. In a RPG without Magic."; - break; - case 132: - printmessage = "I believe i can fly. The Resulst can be seen, now."; - break; - case 133: - printmessage = "I always await an Ambush, even when i'm asleep."; - break; - case 134: - printmessage = "I'm not always right! But i'm never wrong!"; - break; - case 135: - printmessage = "It's so funny to kill them! It should be forbidden! IT'S FORBIDDEN!!!"; - break; - case 136: - printmessage = "Cheat-Mode detected! Installing Virus on Hard, Middle and Soft Disc. Please wait!"; - break; - case 137: - printmessage = "Braindetector activated, calibrating, now searching.........still searching......get a good grip of your mobile....still searching.......no brains found."; - break; - case 138: - printmessage = "Did I not see you yesterday at the mall, with a grey jacket? No? O, than it was a rubbish bag after all!"; - break; - case 139: - printmessage = "What he want, I do not want ... What I want, he does not want ... What we want, is not allowed!"; - break; - case 140: - printmessage = "An Error has appeared while creating an Error Message."; - break; - case 141: - printmessage = "\"I hate when friends come over and ask, \"Do you have a bathroom?\" - \"No, we shit outside.\""; - break; - case 142: - printmessage = "A PC is only as clever as his User."; - break; - case 143: - printmessage = "Access denied, please enter your ID again..."; - break; - case 144: - printmessage = "As a Computer, I find your faith in technology... amusing!"; - break; - case 145: - printmessage = "Eek! A mouse! Plug it out! Eek! It's full of bytes!"; - break; - case 146: - printmessage = "Funny Bugreport #22650: No sound while PC is burning!"; - break; - case 147: - printmessage = "Loading is booooring..."; - break; - case 148: - printmessage = "Loading MP3 playlist..."; - break; - case 149: - printmessage = "Loading silly messages..."; - break; - case 150: - printmessage = "Loading Sprite #559486753...Please wait!"; - break; - case 151: - printmessage = "Loading will continue after a short message from our Sponsor."; - break; - case 152: - printmessage = "Monday morning Quest: Find my Coffee Mug in the Office!"; - break; - case 153: - printmessage = "Out of Money error ... Insert new projekt fundings!"; - break; - case 154: - printmessage = "Please turn off your monitor to continue."; - break; - case 155: - printmessage = "Scanning Mail Folder... emty... not even Spam Mail!"; - break; - case 156: - printmessage = "Searching for Adult Filter..."; - break; - case 157: - printmessage = "Seaching for saved game... not found. Restarting game..."; - break; - case 158: - printmessage = "Spiderpig, Spiderpig ..."; - break; - case 159: - printmessage = "Stop staring at this message or I will stop loading."; - break; - case 160: - printmessage = "The... no, A..., no, wait, sorry, that one sounded better in my head."; - break; - case 161: - printmessage = "There's something written about a chance but I don´t trust this game..."; - break; - case 162: - printmessage = "There is a hole... in your mind."; - break; - case 163: - printmessage = "There is too much CPU usage in zlib.dll!"; - break; - case 164: - printmessage = "Unloading silly messages, not silly enough!"; - break; - case 165: - printmessage = "Updating funny messages..."; - break; - case 166: - printmessage = "Uplink to ISS etablished, downloading weather forecast..."; - break; - case 167: - printmessage = "Uploading user fingerprints to NSA computer..."; - break; - case 168: - printmessage = "Use the mouse, Luke!"; - break; - case 169: - printmessage = "Video ram too small, switching to grid display..."; - break; - case 170: - printmessage = "Waiting some time..."; - break; - case 171: - printmessage = "We're working on the documentation ..."; - break; - case 172: - printmessage = "Warning! CPU temperature reaching critical... Shutting system down..."; - break; - case 173: - printmessage = "We apologize for the fault in loading screen. The responsible parties have been sacked."; - break; - case 174: - printmessage = "We'll be right back after this commercial break."; - break; - case 175: - printmessage = "What's that behind you?"; - break; - case 176: - printmessage = "What are you doing? Stop that!"; - break; - case 177: - printmessage = "When it's done! Got it?"; - break; - case 178: - printmessage = "When you are leaving, please close the door behind you."; - break; - case 179: - printmessage = "Would you like to play a game of...World Domination?"; - break; - case 180: - printmessage = "Wrong CD Key... this Game will now be locked on this Computer for ever."; - break; - case 181: - printmessage = "Yeah but no but yeah but no but yeah but no."; - break; - case 182: - printmessage = "You are here: X"; - break; - case 183: - printmessage = "You are the 1.000.000th visitor! Congratulations! You won a box of tissues - not."; - break; - case 184: - printmessage = "You won´t get this package if you can not ID yourself!"; - break; - case 185: - printmessage = "You really have to find a girlfriend whose name doesn´t end with .jpg!"; - break; - case 186: - printmessage = "Mysterious Strangers visits: 0"; - break; - case 187: - printmessage = "I am a cute computer... really!"; - break; - case 188: - printmessage = "Never seen such a big... never mind..."; - break; - case 189: - printmessage = "Deleting all Celine Dion MP3s ..."; - break; - case 190: - printmessage = "Destroying brain cells... 15 percent... 50 percent... Duuh..."; - break; - case 191: - printmessage = "Cannot translate silly message into english."; - break; - case 192: - printmessage = "Be sure to visit the gift shop on your way out."; - break; - case 193: - printmessage = "Checking for 3d buffer ... Wait, not that one!"; - break; - case 194: - printmessage = "Activating coffee-machine..."; - break; - case 195: - printmessage = "Hehehe! You'll never guess what awaits you here!"; - break; - case 196: - printmessage = "Bacon is my favourite vegetable..."; - break; - case 197: - printmessage = "Do not include , use instead!"; - break; - case 198: - printmessage = "Cannot find Reality.sys… Universe halted."; - break; - case 199: - printmessage = "Good. Out of the door. Line on the left. One cross each. Next. Crucifixion?"; - break; - case 200: - printmessage = "Here I am, brain the size of a planet, and they ask me to load files."; - break; - case 201: - printmessage = "Man, what a mess on your harddisc..."; - break; - case 202: - printmessage = "Hidden DOS secret: Add bugs=off to your config.sys!"; - break; - case 203: - printmessage = "At some point, we'll have our own options.txt, son. One day..."; - break; - case 204: - printmessage = "Attention! This game can change your personality into evil..."; - break; - case 205: - printmessage = "I have the power of... of.. What's my line again?"; - break; - case 206: - printmessage = "Idea for a messagebox: 'This frame was properly rendered!'"; - break; - case 207: - printmessage = "Loading Bluescreen..."; - break; - case 208: - printmessage = "Sponsored by the Umbrella Corporation."; - break; - case 209: - printmessage = "Don´t wake me up, I´m working..."; - break; - case 210: - printmessage = "It´s you again! Don´t you ever sleep?"; - break; - case 211: - printmessage = "No, this is not a silly message"; - break; - case 212: - printmessage = "Can I interest anyone in Fruit or Dessert?"; - break; - case 213: - printmessage = "our Oma is now Pwned by Studio II!"; - break; - case 214: - printmessage = "Detected System: Windows 3.11 - Switching Screen Resolution to 320 x 480 Pixels."; - break; - case 215: - printmessage = "Hey Buddy! Need a cheap WiFi Cable? Only 100$!"; - break; - case 216: - printmessage = "Do you like Scary Movies?"; - break; - case 217: - printmessage = "My missus says that a spline is the mathmatical backbone of the game."; - break; - case 218: - printmessage = "Two wrongs don't make a right, but three rights make a left!"; - break; - case 219: - printmessage = "I'm sensing a soul in search of answers..."; - break; - case 220: - printmessage = "Only silly coders need to optimize their code!"; - break; - case 221: - printmessage = "Uplink to ISS etablished, downloading weather forecast..."; - break; - case 222: - printmessage = "Good luck everyone - hope to see you again in the future!"; - break; - case 223: - printmessage = "A book can also be, a hat..."; - break; - case 224: - printmessage = "West of house, there is a small mailbox here. Exits are east and south."; - break; - case 225: - printmessage = "Don't create multiple postings, use the edit button!"; - break; - case 226: - printmessage = "Do not disturb, system is disturbed already!"; - break; - case 227: - printmessage = "Don't push me. I'm doing my best, but your machine... tztztz..."; - break; - case 228: - printmessage = "... go to spriegel the schmitzel wertzen or something to that effect!"; - break; - case 229: - printmessage = "...Boldly going, where no one has ever gone before. At Least not recently."; - break; - case 230: - printmessage = "Help! Your Keyboard is stuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk..."; - break; - case 231: - printmessage = "General Failure's fault. Not yours."; - break; - case 232: - printmessage = "Deleting previously saved games..."; - break; - case 233: - printmessage = "earching for illegal Software ... just kidding!"; - break; - case 234: - printmessage = "Dude, where's my car?"; - break; - case 235: - printmessage = "Do you really want to start the game? Really?"; - break; - case 236: - printmessage = "Due to lack of system resources, entering slide-show mode..."; - break; - case 237: - printmessage = "Cheater detected. Loading bunnies..."; - break; - case 238: - printmessage = "Even if you die healthy, your dead."; - break; - case 239: - printmessage = "Real Messages: Debugger doesn't work properly! Do you wish do Debug the Debugger with the Debugger?"; - break; - case 240: - printmessage = "Real Messages: Error Do you want to save your stuff or terminate without it? (Y)es ; (N)o."; - break; - case 241: - printmessage = "e're going to be killed! Fascinating."; - break; - case 242: - printmessage = "HOW MAY I SERVE YOU, INFERIOR BEING?"; - break; - case 243: - printmessage = "Didn't find a Dice for GETRANDOMNUMBER(). Please insert one into your CD Player."; - break; - case 244: - printmessage = "Always doing the same is boring! Let's find out how a burning PC looks like!"; - break; - case 245: - printmessage = "The World is a plate and is carried by a Turtle on which stands three elephants. Everything else is wrong."; - break; - case 246: - printmessage = "You don't have facebook??? Now, when you're officialy dead-> Dead people can't play! Stop loading..."; - break; - case 247: - printmessage = "Does a falling tree makes no Sound if there is nobody to here it fall?"; - break; - case 248: - printmessage = "Do you wish do spent all your money to the Project Owner? (Y)es ; No (disabled)."; - break; - case 249: - printmessage = "It should be fair. God go away with your human feelings. It's of course unfair."; - break; - case 250: - printmessage = "\"Ha finally i've got the last word.\"......\"Nearly the last.\""; - break; - case 251: - printmessage = "The part where you all shut up happens now."; - break; - case 252: - printmessage = "My motto is that there are far too many women in the world to waste time with men."; - break; - case 253: - printmessage = "You think i'm not funny? I can be not funny..."; - break; - case 254: - printmessage = "The bigger they are, the harder they fall!"; - break; - case 255: - printmessage = "Computers are useless. They can only give you answers."; - break; - case 256: - printmessage = "Computers are like bikinis. They save people a lot of guesswork."; - break; - case 257: - printmessage = "We have computers, and we may have other weapons of mass destruction."; - break; - case 258: - printmessage = "That's what's cool about working with computers. They don't argue, they remember everything, and they don't drink all your beer."; - break; - case 259: - printmessage = "If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside."; - break; - case 260: - printmessage = "I've noticed lately that the paranoid fear of computers becoming intelligent and taking over the world has almost entirely disappeared from the common culture. Near as I can tell, this coincides with the release of MS-DOS."; - break; - case 261: - printmessage = "The question of whether computers can think is like the question of whether submarines can swim."; - break; - case 262: - printmessage = "It's ridiculous to live 100 years and only be able to remember 30 million bytes. You know, less than a compact disc. The human condition is really becoming more obsolete every minute."; - break; - case 263: - printmessage = "Never trust a computer you can't throw out a window."; - break; - case 264: - printmessage = "Hardware: The parts of a computer system that can be kicked."; - break; - case 265: - printmessage = "Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves."; - break; - case 266: - printmessage = "The Internet? Is that thing still around?"; - break; - case 267: - printmessage = "Any fool can use a computer. Many do."; - break; - case 268: - printmessage = "There are only two industries that refer to their customers as ‘users'."; - break; - case 269: - printmessage = "Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning."; - break; - case 270: - printmessage = "That's the thing about people who think they hate computers. What they really hate is lousy programmers."; - break; - case 271: - printmessage = "Don't worry if it doesn't work right. If everything did, you'd be out of a job."; - break; - case 272: - printmessage = "Measuring programming progress by lines of code is like measuring aircraft building progress by weight."; - break; - case 273: - printmessage = "Writing code has a place in the human hierarchy worth somewhere above grave robbing and beneath managing."; - break; - case 274: - printmessage = "First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack."; - break; - case 275: - printmessage = "First, solve the problem. Then, write the code."; - break; - case 276: - printmessage = "The best thing about a boolean is even if you are wrong, you are only off by a bit."; - break; - case 277: - printmessage = "Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration."; - break; - case 278: - printmessage = "There are only two kinds of programming languages: those people always bitch about and those nobody uses."; - break; - case 279: - printmessage = "I think Microsoft named .Net so it wouldn't show up in a Unix directory listing."; - break; - case 280: - printmessage = "There is no programming language–no matter how structured–that will prevent programmers from making bad programs."; - break; - case 281: - printmessage = "Fifty years of programming language research, and we end up with C++?"; - break; - case 282: - printmessage = "In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg."; - break; - case 283: - printmessage = "One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs."; - break; - case 284: - printmessage = "Fine, Java MIGHT be a good example of what a programming language should be like. But Java applications are good examples of what applications SHOULDN'T be like."; - break; - case 285: - printmessage = "If Java had true garbage collection, most programs would delete themselves upon execution."; - break; - case 286: - printmessage = "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else."; - break; - case 287: - printmessage = "The first 90% of the code accounts for the first 10% of the development time. The remaining 10% of the code accounts for the other 90% of the development time."; - break; - case 288: - printmessage = "If debugging is the process of removing bugs, then programming must be the process of putting them in."; - break; - case 289: - printmessage = "I don't care if it works on your machine! We are not shipping your machine!"; - break; - case 290: - printmessage = "There are two ways to write error-free programs; only the third one works."; - break; - case 291: - printmessage = "You can either have software quality or you can have pointer arithmetic, but you cannot have both at the same time."; - break; - case 292: - printmessage = "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."; - break; - case 293: - printmessage = "Windows NT addresses 2 Gigabytes of RAM, which is more than any application will ever need."; - break; - case 294: - printmessage = "Keyboard not found. Press < F1 > to RESUME."; - break; - case 295: - printmessage = "Any sufficiently advanced bug is indistinguishable from a feature."; - break; - case 296: - printmessage = "Beware of bugs in the above code; I have only proved it correct, not tried it."; - break; - case 297: - printmessage = "bug, n: An elusive creature living in a program that makes it incorrect. The activity of ""debugging"", or removing bugs from a program, ends when people get tired of doing it, not when the bugs are removed."; - break; - case 298: - printmessage = "Don't get suckered in by the comments— they can be terribly misleading. Debug only code"; - break; - case 299: - printmessage = "If the code and the comments disagree, then both are probably wrong."; - break; - case 300: - printmessage = "Once you're done writing the code, never open it again unless you want to see how uncomprehensible and utterly ridiculous it really is."; - break; - case 301: - printmessage = "The generation of random numbers is too important to be left to chance."; - break; - case 302: - printmessage = "The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents."; - break; - case 303: - printmessage = "Sometimes I believe compiler ignores all my comments"; - break; - case 304: - printmessage = ""; - break; - case 305: - printmessage = "You don't need luck. You need enough firepower."; - break; - case 306: - printmessage = "This Game isn't about peace so \"make war\""; - break; - case 307: - printmessage = "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone."; - break; - case 308: - printmessage = "The gap between theory and practice is not as wide in theory as it is in practice."; - break; - case 309: - printmessage = "There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence."; - break; - case 310: - printmessage = "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are–by definition–not smart enough to debug it."; - break; - case 311: - printmessage = "If at first you don't succeed, call it version 1.0"; - break; - case 312: - printmessage = "Rules of Optimization: Rule(1) : Don() 't do it. Rule 2 (for experts only): Don't do it yet."; - break; - case 313: - printmessage = "Programming can be fun, so can cryptography; however they should not be combined."; - break; - case 314: - printmessage = "Computers are good at following instructions, but not at reading your mind."; - break; - case 315: - printmessage = "I just saw my life flash before my eyes and all I could see was a close tag…"; - break; - case 316: - printmessage = "Java: write once, debug everywhere."; - break; - case 317: - printmessage = "All methodologies are based on fear."; - break; - case 318: - printmessage = "Real programmers don't document. If it was hard to write, it should be hard to understand."; - break; - case 319: - printmessage = "If we knew what we were doing, it wouldn't be called research, would it?"; - break; - case 320: - printmessage = "There are two kind of sysadmins: Paranoids and Losers."; - break; - case 321: - printmessage = "We all know Linux is great... it does infinite loops in 5 seconds."; - break; - case 322: - printmessage = "Comments lie. Code doesn't."; - break; - case 323: - printmessage = "Exceed Funny Message File. Creating some new one's."; - break; - case 324: - printmessage = "The Code is the Comment or believe in god."; - break; - case 325: - printmessage = "This message was created by slavery and kids."; - break; - case 326: - printmessage = "Error 404 no game found. Do your homework instead."; - break; - case 327: - printmessage = "It isn't over until it's over!"; - break; - case 328: - printmessage = "We need to train tanks to talk. So we can get another Advance Wars game."; - break; - case 329: - printmessage = "I invented a new word! Plagiarism!"; - case 330: - printmessage = "Why don’t scientists trust atoms? Because they make up everything."; - case 331: - printmessage = "What did the 0 say to the 8? Nice belt!"; - case 332: - printmessage = "Kanbei needs bases!!!"; - case 333: - printmessage = "Andy: What's an airport?"; - case 334: - printmessage = "Wait I can't refill myself? An APC"; - case 335: - printmessage = "Damn those submerged submarines are blocking our way. A fighter pilot"; - case 336: - printmessage = "Advance Wars is dead early 2021. Now we have a living zombie-tank."; - case 337: - printmessage = "Advance Wars 1 shoot that APC. SHOOOOT IT. Why? I said shoot it. It can create infinite supply. Only evil things can do that."; - case 338: - printmessage = "One day Flak will get indirect bombers and this day is near."; - default: - printmessage = "No more funny Messages found. Delete your Harddisk instead"; - break; + printmessage = messages[message]; } printDirectly(printmessage, GameConsole::eINFO); } diff --git a/coreengine/globalutils.cpp b/coreengine/globalutils.cpp index 3e0516bc4..5450f44ca 100644 --- a/coreengine/globalutils.cpp +++ b/coreengine/globalutils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -10,6 +11,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/interpreter.h" #include "coreengine/settings.h" +#include "coreengine/virtualpaths.h" #include "game/gamemap.h" @@ -333,7 +335,7 @@ QStringList GlobalUtils::getFiles(const QString folder, const QStringList filter { QStringList ret; - QStringList paths = {oxygine::Resource::RCC_PREFIX_PATH, Settings::getInstance()->getUserPath()}; + QStringList paths = VirtualPaths::createSearchPath("", false); for (const auto & path : std::as_const(paths)) { QDirIterator dirIter(path + folder, filter, QDir::Files, QDirIterator::Subdirectories); @@ -481,39 +483,6 @@ QString GlobalUtils::makePathRelative(QString file, bool full) return file; } -QFileInfoList GlobalUtils::getInfoList(const QString & folder, const QStringList & list) -{ - QFileInfoList infoList; - infoList.append(QDir(Settings::getInstance()->getUserPath() + folder).entryInfoList(QDir::Dirs)); - auto virtList = QDir(oxygine::Resource::RCC_PREFIX_PATH + folder).entryInfoList(QDir::Dirs); - for (const auto & item : std::as_const(virtList)) - { - bool found = false; - for (const auto & item2 : std::as_const(infoList)) - { - if (item2.baseName() == item.baseName()) - { - found = true; - break; - } - } - if (!found) - { - infoList.append(item); - } - } - if (list.length() > 0) - { - QString path = Settings::getInstance()->getUserPath() + folder; - path.replace("//", "/"); - infoList.append(QDir(path).entryInfoList(list, QDir::Files)); - path = oxygine::Resource::RCC_PREFIX_PATH + folder; - path.replace("//", "/"); - infoList.append(QDir(path).entryInfoList(list, QDir::Files)); - } - return infoList; -} - QUrl GlobalUtils::getUrlForFile(const QString & file) { QUrl url; diff --git a/coreengine/globalutils.h b/coreengine/globalutils.h index 9aa1ca465..49520bbe8 100644 --- a/coreengine/globalutils.h +++ b/coreengine/globalutils.h @@ -32,7 +32,6 @@ class GlobalUtils final : public QObject static qint32 randIntBase(qint32 low, qint32 high); static float randFloatBase(float low, float high); static qreal randDoubleBase(qreal low, qreal high); - static QFileInfoList getInfoList(const QString & folder, const QStringList & list = QStringList()); static QUrl getUrlForFile(const QString & file); static QString getByteArrayString(const QByteArray & bytes); static QByteArray getStringByteArray(const QString & bytes); diff --git a/coreengine/settings.cpp b/coreengine/settings.cpp index 5118153dc..ded8c8740 100644 --- a/coreengine/settings.cpp +++ b/coreengine/settings.cpp @@ -25,6 +25,7 @@ #include "coreengine/audiomanager.h" #include "coreengine/Gamepad.h" #include "coreengine/interpreter.h" +#include "coreengine/virtualpaths.h" const char* const Settings::DEFAULT_AUDIODEVICE = "@@default@@"; @@ -629,6 +630,7 @@ void Settings::setUserPath(const QString newUserPath) } m_userPath = folder; } + VirtualPaths::setSearchPath(m_userPath, m_activeMods); } bool Settings::getSmallScreenDevice() @@ -1042,11 +1044,10 @@ void Settings::setActiveMods(const QStringList activeMods) qint32 i = 0; while (i < m_activeMods.size()) { - QDir dir(getUserPath() + m_activeMods[i]); - QDir dir2( oxygine::Resource::RCC_PREFIX_PATH + m_activeMods[i]); - if (!dir.exists() && !dir2.exists()) + QDir dir(VirtualPaths::find(m_activeMods[i], false)); + if (!dir.exists()) { - CONSOLE_PRINT("Removing mod from active list: " + m_activeMods[i] + " cause it wasn't found.", GameConsole::eWARNING); + CONSOLE_PRINT("Removing mod from active list: " + m_activeMods[i] + " because it wasn't found.", GameConsole::eWARNING); m_activeMods.removeAt(i); } else @@ -1059,7 +1060,7 @@ void Settings::setActiveMods(const QStringList activeMods) { CONSOLE_PRINT("Loaded mod: " + mod, GameConsole::eDEBUG); bool found = false; - QFile file(getUserPath() + mod + "/mod.txt"); + QFile file(VirtualPaths::find(mod + "/mod.txt", false)); if (file.exists()) { file.open(QFile::ReadOnly); @@ -1080,6 +1081,7 @@ void Settings::setActiveMods(const QStringList activeMods) m_activeModVersions.append("1.0.0"); } } + VirtualPaths::setSearchPath(m_userPath, m_activeMods); } bool Settings::getShowIngameCoordinates() @@ -2002,11 +2004,7 @@ void Settings::getModInfos(QString mod, QString & name, QString & description, Q QStringList & tags, QString & thumbnail) { name = mod; - QFile file(Settings::getUserPath() + mod + "/mod.txt"); - if (!file.exists()) - { - file.setFileName(oxygine::Resource::RCC_PREFIX_PATH + mod + "/mod.txt"); - } + QFile file(VirtualPaths::find(mod + "/mod.txt", false)); isCosmetic = false; if (file.exists()) { @@ -2061,10 +2059,16 @@ void Settings::getModInfos(QString mod, QString & name, QString & description, Q QStringList Settings::getAvailableMods() { + QFileInfoList infoList; + auto searchPath = VirtualPaths::findAllRev("mods", false); + for (const auto & entry : searchPath) + { + if (QFile::exists(entry)) + { + infoList.append(QDir(entry).entryInfoList(QDir::Dirs)); + } + } QStringList mods; - QFileInfoList rccinfoList = QDir(QString(oxygine::Resource::RCC_PREFIX_PATH) + "mods").entryInfoList(QDir::Dirs); - QFileInfoList infoList = QDir(Settings::getUserPath() + "mods").entryInfoList(QDir::Dirs); - infoList.append(rccinfoList); for (const auto & info : infoList) { QString folder = GlobalUtils::makePathRelative(info.filePath()); @@ -2218,31 +2222,19 @@ void Settings::setLanguage(const QString language) m_translators.clear(); m_language = language; - QStringList searchPaths; - const QString filename = "translation/lang_" + m_language + ".qm"; - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/" + filename); - searchPaths.append(Settings::getUserPath() + "resources/" + filename); - // make sure to overwrite existing js stuff - for (qint32 i = 0; i < Settings::getMods().size(); i++) - { - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + Settings::getMods().at(i) + "/" + filename); - searchPaths.append(Settings::getUserPath() + Settings::getMods().at(i) + "/" + filename); - } + QStringList searchPaths = VirtualPaths::findAll("resources/translation/lang_" + m_language + ".qm"); for (const auto & file : searchPaths) { - if (QFile::exists(file)) + auto translator = MemoryManagement::createNamedQObject("QTranslator"); + m_translators.append(translator); + if (translator->load(QLocale(m_language), file)) { - auto translator = MemoryManagement::createNamedQObject("QTranslator"); - m_translators.append(translator); - if (translator->load(QLocale(m_language), file)) - { - CONSOLE_PRINT("Loaded language file " + file + " for language " + m_language, GameConsole::eDEBUG); - QCoreApplication::installTranslator(translator.get()); - } - else - { - m_translators.removeLast(); - } + CONSOLE_PRINT("Loaded language file " + file + " for language " + m_language, GameConsole::eDEBUG); + QCoreApplication::installTranslator(translator.get()); + } + else + { + m_translators.removeLast(); } } } @@ -2251,12 +2243,7 @@ QStringList Settings::getLanguageNames() { QLocale english("en"); QStringList items = {english.nativeLanguageName()}; - QStringList paths = {QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/translation/", "resources/translation/"}; - for (qint32 i = 0; i < Settings::getMods().size(); i++) - { - paths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + Settings::getMods().at(i) + "/translation"); - paths.append(Settings::getUserPath() + Settings::getMods().at(i) + "/translation"); - } + QStringList paths = VirtualPaths::createSearchPath("resources/translation/"); QStringList filter; filter << "*.qm"; for (const QString & path : std::as_const(paths)) @@ -2279,7 +2266,7 @@ QStringList Settings::getLanguageNames() QStringList Settings::getLanguageIds() { QStringList languages = {"en"}; - QStringList paths = {QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/translation/", "resources/translation/"}; + QStringList paths = VirtualPaths::createSearchPath("resources/translation/"); QStringList filter; filter << "*.qm"; for (const QString & path : std::as_const(paths)) @@ -2301,7 +2288,7 @@ QStringList Settings::getLanguageIds() qint32 Settings::getCurrentLanguageIndex() { qint32 current = 0; - QStringList paths = {QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/translation/", "resources/translation/"}; + QStringList paths = VirtualPaths::createSearchPath("resources/translation/"); QStringList filter; filter << "*.qm"; qint32 i = 0; diff --git a/coreengine/sounds/ondemandsound.cpp b/coreengine/sounds/ondemandsound.cpp index 460590406..2b104cb0b 100644 --- a/coreengine/sounds/ondemandsound.cpp +++ b/coreengine/sounds/ondemandsound.cpp @@ -12,6 +12,7 @@ void AudioManager::fillSoundCache(qint32 count, QString folder, QString file) { + #ifdef AUDIOSUPPORT if (!m_noAudio) { diff --git a/coreengine/virtualpaths.cpp b/coreengine/virtualpaths.cpp new file mode 100644 index 000000000..1ee17e45b --- /dev/null +++ b/coreengine/virtualpaths.cpp @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include + +#include "coreengine/virtualpaths.h" + +const QStringList VirtualPaths::emptyList; + +struct SearchPath final +{ + QString root; + bool isModPath = false; +}; +static QList searchPath; + +void VirtualPaths::setSearchPath(const QString& userPath, const QStringList& mods) +{ + CONSOLE_PRINT("Initializing VFS...", GameConsole::eINFO); + + searchPath.clear(); + + searchPath.append({ userPath }); + +#ifndef USEAPPCONFIGPATH + // USEAPPCONFIGPATH is primarily set on Linux, where the "current directory" of programs launched from the start + // menu is normally the user's home directory. This is very unexpected behavior, and this should not be checked. + if (QFileInfo(".") != QFileInfo(userPath)) + { + searchPath.append({ "." }); + } +#endif + + for (const auto & mod : std::as_const(mods)) + { + searchPath.append({ userPath + mod, true }); + searchPath.append({ oxygine::Resource::RCC_PREFIX_PATH + mod, true }); + } + +#ifdef DEPLOY_RESOURCES_AS_FOLDER + searchPath.append({ QCoreApplication::applicationDirPath() }); + +#ifdef __linux__ + searchPath.append({ QCoreApplication::applicationDirPath() + "/../share/commander_wars" }); +#endif +#endif + + searchPath.append({ oxygine::Resource::RCC_PREFIX_PATH }); + + for (auto & path : searchPath) + { + CONSOLE_PRINT("- Path: " + path.root + (path.isModPath ? " (mod data)" : ""), GameConsole::eINFO); + } +} + +struct ProcessedName final +{ + QString path; + bool isResources = false; + QString resourcesPath = ""; +}; +static ProcessedName processName(const QString& pName) +{ + // Strip leading slashes + QString name = pName; + while (name.startsWith("/")) + name = name.last(name.length() - 1); + + // Search for the root directory itself. + if (name.isEmpty()) + { + return { "" }; + } + // Search for the resources directory itself. + else if (name == "resources" || name == "resources/") + { + return { "/" + name, true, name.last(name.length() - 9) }; + } + // Search for a file in the resources directory + else if (name.startsWith("resources/")) + { + return { "/" + name, true, name.last(name.length() - 9) }; + } + // Search for a file anywhere else + else + { + return { "/" + name }; + } +} + +QString VirtualPaths::find(const QString& pName, bool checkMods) { + auto name = processName(pName); + + QString newPath; + for (auto & path : searchPath) + { + if (!checkMods && path.isModPath) + { + continue; + } + + newPath = path.root + name.path; + if (QFileInfo(newPath).exists()) + { + return newPath; + } + + if (name.isResources && path.isModPath) + { + newPath = path.root + name.resourcesPath; + if (QFileInfo(newPath).exists()) + { + return newPath; + } + } + } + + return ":/this_should_not_exist" + name.path; +} + +QStringList VirtualPaths::createSearchPathInternal(const QString& pName, bool checkMods, bool firstPriority) +{ + auto name = processName(pName); + + QStringList list; + QString newPath; + for (auto & path : searchPath) + { + if (!checkMods && path.isModPath) + { + continue; + } + + newPath = path.root + name.path; + list.append(newPath); + + if (name.isResources && path.isModPath) + { + newPath = path.root + name.resourcesPath; + list.append(newPath); + } + } + + if (!firstPriority) + { + std::reverse(list.begin(), list.end()); + } + return list; +} + +QStringList VirtualPaths::findAllInternal(const QString& pName, bool checkMods, bool firstPriority) +{ + auto name = processName(pName); + + QStringList list; + QString newPath; + for (auto & path : searchPath) + { + if (!checkMods && path.isModPath) + { + continue; + } + + newPath = path.root + name.path; + if (QFileInfo(newPath).exists()) + { + list.append(newPath); + } + + if (name.isResources && path.isModPath) + { + newPath = path.root + name.resourcesPath; + if (QFileInfo(newPath).exists()) + { + list.append(newPath); + } + } + } + + if (!firstPriority) + { + std::reverse(list.begin(), list.end()); + } + return list; +} + +QFileInfoList VirtualPaths::list(const QString& name, const QStringList& filters, bool checkMods) +{ + QSet foundBaseNames; + QFileInfoList infoList; + + for (auto & path : VirtualPaths::createSearchPathRev(name, checkMods)) + { + QFileInfo pathInfo(path); + if (pathInfo.exists() && pathInfo.isDir()) + { + for (const auto & entry : QDir(path).entryInfoList(QDir::Dirs)) + { + if (!foundBaseNames.contains(entry.baseName())) + { + infoList.append(entry); + foundBaseNames.insert(entry.baseName()); + } + } + + if (!filters.isEmpty()) + { + for (const auto & entry : QDir(path).entryInfoList(filters, QDir::Files)) + { + if (!foundBaseNames.contains(entry.baseName())) + { + infoList.append(entry); + foundBaseNames.insert(entry.baseName()); + } + } + } + } + } + + return infoList; +} diff --git a/coreengine/virtualpaths.h b/coreengine/virtualpaths.h new file mode 100644 index 000000000..7d7de8a94 --- /dev/null +++ b/coreengine/virtualpaths.h @@ -0,0 +1,63 @@ +#ifndef COREENGINE_VFS_H +#define COREENGINE_VFS_H + +#include +#include +#include + +class VirtualPaths final +{ + public: + + static void setSearchPath(const QString& userPath, const QStringList& mods = emptyList); + + /** + * Locates the real path for a resource, or a file path guaranteed not to exist if it is not found. + */ + static QString find(const QString& name, bool checkMods = true); + + /** + * Finds all real paths that match a particular file name. + */ + static QStringList findAll(const QString& name, bool checkMods = true) { + return findAllInternal(name, checkMods, false); + } + + /** + * Finds all real paths that match a particular file name in reverse order. + */ + static QStringList findAllRev(const QString& name, bool checkMods = true) { + return findAllInternal(name, checkMods, true); + } + + /** + * Builds the search path for a particular file path in reverse order. + */ + static QStringList createSearchPath(const QString& name, bool checkMods = true) { + return createSearchPathInternal(name, checkMods, false); + } + + /** + * Builds the search path for a particular file path in reverse order. + */ + static QStringList createSearchPathRev(const QString& name, bool checkMods = true) { + return createSearchPathInternal(name, checkMods, true); + } + + /** + * Lists all files in a particular directory. + */ + static QFileInfoList list(const QString& name, const QStringList& filters = emptyList, bool checkMods = true); + + private: + + VirtualPaths() = delete; + ~VirtualPaths() = delete; + + static QStringList createSearchPathInternal(const QString& name, bool checkMods = true, bool firstPriority = false); + static QStringList findAllInternal(const QString& name, bool checkMods = true, bool firstPriority = false); + + static const QStringList emptyList; +}; + +#endif // COREENGINE_VFS_H diff --git a/coreengine/workerthread.cpp b/coreengine/workerthread.cpp index 0f30d4260..c1fbc2b0a 100644 --- a/coreengine/workerthread.cpp +++ b/coreengine/workerthread.cpp @@ -12,6 +12,7 @@ #include "coreengine/workerthread.h" #include "coreengine/gameconsole.h" #include "coreengine/userdata.h" +#include "coreengine/virtualpaths.h" #include "menue/mainwindow.h" @@ -126,15 +127,7 @@ void WorkerThread::start() pConsole->init(); UiFactory::getInstance(); // load General-Base Scripts - QStringList searchPaths; - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/scripts/general"); - searchPaths.append("resources/scripts/general"); - // make sure to overwrite existing js stuff - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + "/scripts/general"); - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/scripts/general"); - } + QStringList searchPaths = VirtualPaths::createSearchPath("resources/scripts/general"); for (auto & path : searchPaths) { QStringList filter; diff --git a/game/campaign.cpp b/game/campaign.cpp index c62550e7e..edc13bffb 100644 --- a/game/campaign.cpp +++ b/game/campaign.cpp @@ -11,6 +11,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/settings.h" #include "coreengine/mainapp.h" +#include "coreengine/virtualpaths.h" const char* const Campaign::scriptName = "campaignScript"; @@ -71,38 +72,38 @@ Campaign::CampaignMapInfo Campaign::getCampaignMaps() files.removeAt(0); for (qint32 i = 0; i < files.size(); ++i) { - if (QFile::exists(Settings::getInstance()->getUserPath() + folder + files[i])) + QString path = VirtualPaths::find(folder + files[i]); + if (QFile::exists(path)) { - files[i] = Settings::getInstance()->getUserPath() + folder + files[i]; - CONSOLE_PRINT("adding campaign map: " + Settings::getInstance()->getUserPath() + folder + files[i], GameConsole::eDEBUG); - } - else if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + folder + files[i])) - { - CONSOLE_PRINT("adding campaign map: " + QString(oxygine::Resource::RCC_PREFIX_PATH) + folder + files[i], GameConsole::eDEBUG); - files[i] = oxygine::Resource::RCC_PREFIX_PATH + folder + files[i]; + files[i] = path; + CONSOLE_PRINT("adding campaign map: " + path, GameConsole::eDEBUG); } } - addDeveloperMaps(Settings::getInstance()->getUserPath(), folder, files); - addDeveloperMaps(oxygine::Resource::RCC_PREFIX_PATH, folder, files); + + QStringList searchPath = VirtualPaths::createSearchPath(folder, false); + for (qint32 i = 0; i < searchPath.size(); i++) + { + addDeveloperMaps(searchPath[i], files); + } } return CampaignMapInfo(folder, files); } -void Campaign::addDeveloperMaps(const QString & prefix, const QString & folder, QStringList & files) +void Campaign::addDeveloperMaps(const QString & prefix, QStringList & files) { if (GameConsole::getDeveloperMode()) { QStringList filter; filter << "*.map"; - QDirIterator dirIter(prefix + folder, filter, QDir::Files, QDirIterator::Subdirectories); + QDirIterator dirIter(prefix, filter, QDir::Files, QDirIterator::Subdirectories); while (dirIter.hasNext()) { dirIter.next(); QString file = dirIter.fileName(); if (!files.contains(file)) { - CONSOLE_PRINT("adding campaign folder map: " + prefix + folder + file, GameConsole::eDEBUG); - files.append(prefix + folder + file); + CONSOLE_PRINT("adding campaign folder map: " + prefix + file, GameConsole::eDEBUG); + files.append(prefix + file); } } } diff --git a/game/campaign.h b/game/campaign.h index 95616e4b9..819b7f819 100644 --- a/game/campaign.h +++ b/game/campaign.h @@ -73,7 +73,7 @@ class Campaign final : public QObject, public FileSerializable, public JsThis * @param folder * @param files */ - void addDeveloperMaps(const QString & prefix, const QString & folder, QStringList & files); + void addDeveloperMaps(const QString & prefix, QStringList & files); /** * @brief getCampaignMapData * @param pCampaignMapData diff --git a/game/gameanimation/gameanimation.cpp b/game/gameanimation/gameanimation.cpp index 1e18ec7fe..c04bd7d33 100644 --- a/game/gameanimation/gameanimation.cpp +++ b/game/gameanimation/gameanimation.cpp @@ -13,6 +13,7 @@ #include "coreengine/interpreter.h" #include "coreengine/settings.h" #include "coreengine/audiomanager.h" +#include "coreengine/virtualpaths.h" GameAnimation::GameAnimation(quint32 frameTime, GameMap* pMap) : m_frameTime(frameTime / Settings::getInstance()->getAnimationSpeed()), @@ -251,17 +252,10 @@ void GameAnimation::addSprite3(QString spriteID, float offsetX, float offsetY, Q else { QImage img; - if (QFile::exists(spriteID)) + QString imgPath = VirtualPaths::find(spriteID); + if (QFile::exists(imgPath)) { - img = QImage(spriteID); - } - else if (QFile::exists(Settings::getInstance()->getUserPath() + spriteID)) - { - img = QImage(Settings::getInstance()->getUserPath() + spriteID); - } - else if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + spriteID)) - { - img = QImage(oxygine::Resource::RCC_PREFIX_PATH + spriteID); + img = QImage(imgPath); } else { diff --git a/game/gameanimation/gameanimationcapture.cpp b/game/gameanimation/gameanimationcapture.cpp index 6ae2a3c35..161f11ae7 100644 --- a/game/gameanimation/gameanimationcapture.cpp +++ b/game/gameanimation/gameanimationcapture.cpp @@ -6,6 +6,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/audiomanager.h" #include "coreengine/interpreter.h" +#include "coreengine/virtualpaths.h" #include "spritingsupport/spritecreator.h" @@ -47,11 +48,7 @@ void GameAnimationCapture::addBuildingSprite(const QString spriteID, Player* sta m_buildingResAnim = MemoryManagement::create(); m_captureBuildingResAnim = MemoryManagement::create(); } - QString path = Settings::getInstance()->getUserPath() + pAnim->getResPath(); - if (!QFile::exists(path)) - { - path = oxygine::Resource::RCC_PREFIX_PATH + pAnim->getResPath(); - } + QString path = VirtualPaths::find(pAnim->getResPath()); if (QFile::exists(path)) { QImage preCaptureImage(path); @@ -64,7 +61,7 @@ void GameAnimationCapture::addBuildingSprite(const QString spriteID, Player* sta } else { - CONSOLE_PRINT("Unable to locate file: " + path, GameConsole::eDEBUG); + CONSOLE_PRINT("Unable to locate file: " + pAnim->getResPath(), GameConsole::eDEBUG); } } else diff --git a/game/gameanimation/gameanimationdialog.cpp b/game/gameanimation/gameanimationdialog.cpp index fb1c99246..124261737 100644 --- a/game/gameanimation/gameanimationdialog.cpp +++ b/game/gameanimation/gameanimationdialog.cpp @@ -10,6 +10,7 @@ #include "coreengine/interpreter.h" #include "coreengine/audiomanager.h" +#include "coreengine/virtualpaths.h" #include "resource_management/gamemanager.h" #include "resource_management/fontmanager.h" @@ -350,13 +351,10 @@ void GameAnimationDialog::loadBackground(const QString file) if (!file.isEmpty()) { QImage img; - if (QFile::exists(Settings::getInstance()->getUserPath() + file)) + QString imgPath = VirtualPaths::find(file); + if (QFile::exists(imgPath)) { - img = QImage(Settings::getInstance()->getUserPath() + file); - } - else if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + file)) - { - img = QImage(oxygine::Resource::RCC_PREFIX_PATH + file); + img = QImage(imgPath); } oxygine::spSingleResAnim pAnim = MemoryManagement::create(); Mainapp::getInstance()->loadResAnim(pAnim, img, 1, 1, 1); diff --git a/game/gamescript.cpp b/game/gamescript.cpp index fa2720343..383b6dcfa 100644 --- a/game/gamescript.cpp +++ b/game/gamescript.cpp @@ -8,6 +8,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/settings.h" #include "coreengine/mainapp.h" +#include "coreengine/virtualpaths.h" #include "menue/basegamemenu.h" @@ -62,19 +63,7 @@ void GameScript::init() Interpreter* pInterpreter = Interpreter::getInstance(); if (!m_scriptFile.isEmpty()) { - QFile file; - if (QFile::exists(m_scriptFile)) - { - file.setFileName(m_scriptFile); - } - else if (QFile::exists(Settings::getInstance()->getUserPath() + m_scriptFile)) - { - file.setFileName(Settings::getInstance()->getUserPath() + m_scriptFile); - } - else if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + m_scriptFile)) - { - file.setFileName(oxygine::Resource::RCC_PREFIX_PATH + m_scriptFile); - } + QFile file = VirtualPaths::find(m_scriptFile); if (file.exists()) { CONSOLE_PRINT("Loading map script " + file.fileName(), GameConsole::eDEBUG); diff --git a/game/player.cpp b/game/player.cpp index 3f6b9ba6a..b5445e8ef 100644 --- a/game/player.cpp +++ b/game/player.cpp @@ -1,6 +1,7 @@ +#include "coreengine/filesupport.h" #include "coreengine/globalutils.h" #include "coreengine/audiomanager.h" -#include "coreengine/filesupport.h" +#include "coreengine/virtualpaths.h" #include "gameinput/basegameinputif.h" #include "gameinput/humanplayerinput.h" @@ -227,14 +228,7 @@ bool Player::loadTableFromFile(const QString tablename) { CONSOLE_PRINT("Player::loadTableFromFile " + tablename, GameConsole::eDEBUG); bool found = false; - QStringList searchPaths; - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - searchPaths.append(oxygine::Resource::RCC_PREFIX_PATH + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - } - searchPaths.append(Settings::getInstance()->getUserPath() + "resources/images/colortables/"); - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/images/colortables/"); + QStringList searchPaths = VirtualPaths::createSearchPathRev("resources/images/colortables/"); for (auto & path : searchPaths) { if (QFile::exists(path + tablename + ".png")) @@ -398,14 +392,7 @@ bool Player::colorToTableInTable(QColor baseColor) { CONSOLE_PRINT("Player::colorToTableInTable", GameConsole::eDEBUG); bool found = false; - QStringList searchPaths; - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - } - searchPaths.append(Settings::getInstance()->getUserPath() + "resources/images/colortables/"); - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/images/colortables/"); + QStringList searchPaths = VirtualPaths::createSearchPathRev("resources/images/colortables/"); for (qint32 i = 0; i < searchPaths.size(); i++) { QString path = searchPaths[i]; @@ -540,14 +527,7 @@ oxygine::spResAnim Player::getNeutralTableAnim() if (m_neutralTableAnim.get() == nullptr) { m_neutralTableAnim = MemoryManagement::create(); - QStringList searchPaths; - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - searchPaths.append(oxygine::Resource::RCC_PREFIX_PATH + Settings::getInstance()->getMods().at(i) + "/images/colortables/"); - } - searchPaths.append("resources/images/colortables/"); - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/images/colortables/"); + QStringList searchPaths = VirtualPaths::createSearchPathRev("resources/images/colortables/"); for (auto & path : searchPaths) { if (QFile::exists(path + "neutral.png")) diff --git a/game/terrain.cpp b/game/terrain.cpp index cc4792c89..9765ec93d 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -5,6 +5,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/interpreter.h" +#include "coreengine/virtualpaths.h" #include "resource_management/terrainmanager.h" #include "resource_management/gameanimationmanager.h" @@ -682,17 +683,10 @@ void Terrain::loadBaseSprite(const QString & spriteID, qint32 frameTime, qint32 addChild(pSprite); m_terrainSpriteName = spriteID; QImage img; - if (QFile::exists(m_terrainSpriteName)) + QString imgPath = VirtualPaths::find(m_terrainSpriteName); + if (QFile::exists(imgPath)) { - img = QImage(m_terrainSpriteName); - } - else if (QFile::exists(Settings::getInstance()->getUserPath() + m_terrainSpriteName)) - { - img = QImage(Settings::getInstance()->getUserPath() + m_terrainSpriteName); - } - else - { - img = QImage(oxygine::Resource::RCC_PREFIX_PATH + m_terrainSpriteName); + img = QImage(imgPath); } oxygine::spSingleResAnim pAnim = MemoryManagement::create(); Mainapp::getInstance()->loadResAnim(pAnim, img, 1, 1, 1); @@ -717,9 +711,7 @@ bool Terrain::customSpriteExists() const TerrainManager* pTerrainManager = TerrainManager::getInstance(); oxygine::ResAnim* pAnim = pTerrainManager->getResAnim(m_terrainSpriteName, oxygine::error_policy::ep_ignore_error); return pAnim != nullptr || - QFile::exists(m_terrainSpriteName) || - QFile::exists(Settings::getInstance()->getUserPath() + m_terrainSpriteName) || - QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + m_terrainSpriteName); + QFile::exists(VirtualPaths::find(m_terrainSpriteName)); } void Terrain::updateFlowSprites(TerrainFindingSystem* pPfs, bool applyRulesPalette) diff --git a/ingamescriptsupport/scriptdialogdialog.cpp b/ingamescriptsupport/scriptdialogdialog.cpp index 68a536d25..4539da86e 100644 --- a/ingamescriptsupport/scriptdialogdialog.cpp +++ b/ingamescriptsupport/scriptdialogdialog.cpp @@ -11,6 +11,7 @@ #include "coreengine/interpreter.h" #include "coreengine/globalutils.h" +#include "coreengine/virtualpaths.h" #include "objects/dialogs/filedialog.h" #include "objects/base/dropdownmenusprite.h" @@ -292,17 +293,10 @@ void ScriptDialogDialog::loadBackground(QString filename, qint32 index) if (!filename.isEmpty()) { QImage image; - if (QFile::exists(filename)) + QString imgPath = VirtualPaths::find(filename); + if (QFile::exists(imgPath)) { - image = QImage(filename); - } - else if (QFile::exists(Settings::getInstance()->getUserPath() + filename)) - { - image = QImage(Settings::getInstance()->getUserPath() + filename); - } - else if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + filename)) - { - image = QImage(oxygine::Resource::RCC_PREFIX_PATH + filename); + image = QImage(imgPath); } oxygine::spResAnim pAnim = MemoryManagement::create(); m_backgroundAnims[index] = pAnim; diff --git a/main.cpp b/main.cpp index 8f9371857..a5f7bb35f 100644 --- a/main.cpp +++ b/main.cpp @@ -11,6 +11,7 @@ #include "coreengine/mainapp.h" #include "coreengine/userdata.h" #include "coreengine/gameconsole.h" +#include "coreengine/virtualpaths.h" #include "coreengine/metatyperegister.h" #include "coreengine/globalutils.h" diff --git a/menue/creditsmenue.cpp b/menue/creditsmenue.cpp index e9e356323..839551b3b 100644 --- a/menue/creditsmenue.cpp +++ b/menue/creditsmenue.cpp @@ -10,6 +10,7 @@ #include "coreengine/gameconsole.h" #include "coreengine/mainapp.h" #include "coreengine/audiomanager.h" +#include "coreengine/virtualpaths.h" #include "resource_management/backgroundmanager.h" #include "resource_management/objectmanager.h" @@ -56,16 +57,8 @@ CreditsMenue::CreditsMenue() connect(this, &CreditsMenue::sigExitMenue, this, &CreditsMenue::exitMenue, Qt::QueuedConnection); QFile file; - QString basePath = "resources/credits/credits.cred"; - if (QFile::exists(oxygine::Resource::RCC_PREFIX_PATH + basePath)) - { - file.setFileName(oxygine::Resource::RCC_PREFIX_PATH + basePath); - } - else - { - file.setFileName(basePath); - } - file.open(QIODevice::ReadOnly | QIODevice::Truncate); + file.setFileName(VirtualPaths::find("resources/credits/credits.cred")); + file.open(QIODevice::ReadOnly); QTextStream stream(&file); while (!stream.atEnd()) { diff --git a/menue/editormenue.cpp b/menue/editormenue.cpp index 8346474d4..edec569d2 100644 --- a/menue/editormenue.cpp +++ b/menue/editormenue.cpp @@ -493,7 +493,7 @@ void EditorMenue::showSaveMap() QString path = Settings::getInstance()->getUserPath() + "maps"; spFileDialog fileDialog = MemoryManagement::create(path, wildcards, true, m_pMap->getMapName(), false, tr("Save")); addChild(fileDialog); - connect(fileDialog.get(), &FileDialog::sigFileSelected, this, &EditorMenue::saveMap, Qt::QueuedConnection); + connect(fileDialog.get(), &FileDialog::sigFileSelected, this, &EditorMenue::saveMap, Qt::QueuedConnection); connect(fileDialog.get(), &FileDialog::sigCancel, this, &EditorMenue::editFinishedCanceled, Qt::QueuedConnection); setFocused(false); } @@ -2198,7 +2198,7 @@ void EditorMenue::exitEditor() void EditorMenue::autosave() { CONSOLE_PRINT("EditorMenue::autosave", GameConsole::eDEBUG); - QString filename = "maps/autosave.map"; + QString filename = Settings::getInstance()->getUserPath() + "maps/autosave.map"; if (filename.endsWith(".map")) { QFile file(filename); diff --git a/objects/dialogs/dialogawbwrecorddownloader.h b/objects/dialogs/dialogawbwrecorddownloader.h index b2e3d04b2..60aa9c8b1 100644 --- a/objects/dialogs/dialogawbwrecorddownloader.h +++ b/objects/dialogs/dialogawbwrecorddownloader.h @@ -29,7 +29,7 @@ private slots: void downloadResult(bool success); void onNewProgress(qint64 bytesReceived, qint64 bytesTotal); private: - AwbwReplayDownloader m_awbwreplaydownloader{"data/records/", this}; + AwbwReplayDownloader m_awbwreplaydownloader{Settings::getInstance()->getUserPath() + "data/records/", this}; QString m_userName; QString m_password; QString m_replay; diff --git a/objects/dialogs/filedialog.cpp b/objects/dialogs/filedialog.cpp index 6c6bcfb4e..6e78d551d 100644 --- a/objects/dialogs/filedialog.cpp +++ b/objects/dialogs/filedialog.cpp @@ -8,6 +8,7 @@ #include "coreengine/mainapp.h" #include "coreengine/globalutils.h" #include "coreengine/interpreter.h" +#include "coreengine/virtualpaths.h" #include "resource_management/objectmanager.h" @@ -184,9 +185,8 @@ void FileDialog::showFolder(QString folder) m_Items.clear(); m_ResAnims.clear(); - QDir dir(Settings::getInstance()->getUserPath() + folder); - QDir virtDir(oxygine::Resource::RCC_PREFIX_PATH + folder); - if (!dir.exists() && !virtDir.exists()) + QDir dir(VirtualPaths::find(folder)); + if (!dir.exists()) { if (!folder.isEmpty()) { @@ -203,7 +203,7 @@ void FileDialog::showFolder(QString folder) else { QStringList list = m_DropDownmenu->getCurrentItemText().split(";"); - infoList = GlobalUtils::getInfoList(folder, list); + infoList = VirtualPaths::list(folder, list); } qint32 itemCount = 0; for (qint32 i = 0; i < infoList.size(); i++) diff --git a/objects/dialogs/folderdialog.cpp b/objects/dialogs/folderdialog.cpp index fd713fc78..0bbe8b2fd 100644 --- a/objects/dialogs/folderdialog.cpp +++ b/objects/dialogs/folderdialog.cpp @@ -8,6 +8,7 @@ #include "coreengine/interpreter.h" #include "coreengine/mainapp.h" #include "coreengine/globalutils.h" +#include "coreengine/virtualpaths.h" #include "resource_management/objectmanager.h" @@ -50,9 +51,8 @@ FolderDialog::FolderDialog(QString startFolder) auto* pCurrentFolder = m_CurrentFolder.get(); m_OkButton->addEventListener(oxygine::TouchEvent::CLICK, [this, pCurrentFolder](oxygine::Event*) { - QDir folder(pCurrentFolder->getCurrentText()); - QDir virtFolder(oxygine::Resources::RCC_PREFIX_PATH + pCurrentFolder->getCurrentText()); - if (folder.exists() || virtFolder.exists()) + QDir folder(VirtualPaths::find(pCurrentFolder->getCurrentText())); + if (folder.exists()) { emit sigFolderSelected(pCurrentFolder->getCurrentText()); } @@ -98,9 +98,8 @@ void FolderDialog::showFolder(QString folder) folder = QDir(folder).absolutePath(); folder = GlobalUtils::makePathRelative(folder); m_Items.clear(); - QDir dir(Settings::getInstance()->getUserPath() + folder); - QDir virtDir(oxygine::Resource::RCC_PREFIX_PATH + folder); - if (!dir.exists() && !virtDir.exists()) + QDir dir(VirtualPaths::find(folder)); + if (!dir.exists()) { if (!folder.isEmpty()) { @@ -118,7 +117,7 @@ void FolderDialog::showFolder(QString folder) } else { - infoList = GlobalUtils::getInfoList(folder); + infoList = VirtualPaths::list(folder); } qint32 itemCount = 0; diff --git a/objects/mapselection.cpp b/objects/mapselection.cpp index ca590fcb6..43eec06a1 100644 --- a/objects/mapselection.cpp +++ b/objects/mapselection.cpp @@ -4,6 +4,7 @@ #include "coreengine/userdata.h" #include "coreengine/globalutils.h" #include "coreengine/gameconsole.h" +#include "coreengine/virtualpaths.h" #include "resource_management/objectmanager.h" #include "resource_management/fontmanager.h" @@ -113,9 +114,7 @@ void MapSelection::changeFolder(QString folder) } newFolder = QDir(newFolder).absolutePath(); newFolder = GlobalUtils::makePathRelative(newFolder); - QStringList searchPaths; - searchPaths.append(Settings::getInstance()->getUserPath() + newFolder); - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + newFolder); + QStringList searchPaths = VirtualPaths::createSearchPathRev(newFolder); CONSOLE_PRINT("MapSelection::changeFolder. Relative Path: " + newFolder, GameConsole::eDEBUG); m_Files.clear(); QStringList filterList; @@ -188,8 +187,7 @@ void MapSelection::addFiles(const QString & newFolder, const QStringList & searc { QString currentPath = infoItem.canonicalFilePath(); QDirIterator iter(path, filterList, QDir::Files, QDirIterator::Subdirectories); - QDirIterator iter2(oxygine::Resources::RCC_PREFIX_PATH + item, filterList, QDir::Files, QDirIterator::Subdirectories); - if (!iter.hasNext() && !iter2.hasNext()) + if (!iter.hasNext()) { continue; } diff --git a/resource_management/fontmanager.cpp b/resource_management/fontmanager.cpp index 5da84d3e4..d68b25758 100644 --- a/resource_management/fontmanager.cpp +++ b/resource_management/fontmanager.cpp @@ -1,5 +1,7 @@ #include +#include "coreengine/virtualpaths.h" + #include "resource_management/fontmanager.h" const char* const FontManager::MAINFONT = "main"; @@ -13,14 +15,7 @@ FontManager::FontManager() #ifdef GRAPHICSUPPORT Interpreter::setCppOwnerShip(this); setObjectName("FontManager"); - QStringList searchFolders; - searchFolders.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/fonts/"); - searchFolders.append(Settings::getInstance()->getUserPath() + "resources/fonts/"); - QStringList mods = Settings::getInstance()->getMods(); - for (const auto & mod : std::as_const(mods)) - { - searchFolders.append(Settings::getInstance()->getUserPath() + mod + "/fonts/"); - } + QStringList searchFolders = VirtualPaths::createSearchPath("resources/fonts/"); for (qint32 i = 0; i < searchFolders.size(); ++i) { QString folder = searchFolders[i]; diff --git a/resource_management/movementtablemanager.cpp b/resource_management/movementtablemanager.cpp index 6005f822d..e1f372d25 100644 --- a/resource_management/movementtablemanager.cpp +++ b/resource_management/movementtablemanager.cpp @@ -1,6 +1,8 @@ #include #include +#include "coreengine/virtualpaths.h" + #include "resource_management/movementtablemanager.h" #include "modding/csvtableimporter.h" @@ -27,11 +29,7 @@ void MovementTableManager::loadAll() Interpreter* pInterpreter = Interpreter::getInstance(); QTemporaryDir tempDir = Settings::getInstance()->newTempDir(); QStringList data; - QFile file("resources/scripts/movementtables/movement_csv_import.txt"); - if (!file.exists()) - { - file.setFileName(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/scripts/movementtables/movement_csv_import.txt"); - } + QFile file(VirtualPaths::find("resources/scripts/movementtables/movement_csv_import.txt")); file.open(QIODevice::ReadOnly); QTextStream stream(&file); QString jsHeader = stream.readAll(); diff --git a/resource_management/ressourcemanagement.h b/resource_management/ressourcemanagement.h index a0cccfcc2..5faab29e1 100644 --- a/resource_management/ressourcemanagement.h +++ b/resource_management/ressourcemanagement.h @@ -12,6 +12,7 @@ #include "coreengine/interpreter.h" #include "coreengine/settings.h" #include "coreengine/mainapp.h" +#include "coreengine/virtualpaths.h" template @@ -140,24 +141,10 @@ void RessourceManagement::loadRessources(QString resPath) { if (!resPath.isEmpty() && !Mainapp::getInstance()->getNoUi()) { - if (QFile::exists(QString(RCC_PREFIX_PATH) + "resources/" + resPath)) + QStringList searchPath = VirtualPaths::createSearchPath("resources/" + resPath); + for (qint32 i = 0; i < searchPath.size(); i++) { - oxygine::Resources::loadXML(QString(RCC_PREFIX_PATH) + "resources/" + resPath); - } - if (QFile::exists(Settings::getInstance()->getUserPath() + "resources/" + resPath)) - { - oxygine::Resources::loadXML(Settings::getInstance()->getUserPath() + "resources/" + resPath); - } - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - if (QFile::exists(QString(RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + resPath)) - { - oxygine::Resources::loadXML(QString(RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + resPath); - } - if (QFile::exists(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + resPath)) - { - oxygine::Resources::loadXML(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + resPath); - } + oxygine::Resources::loadXML(searchPath[i]); } } } @@ -224,14 +211,7 @@ QStringList RessourceManagement::getSearchPaths() QStringList searchPaths; if (!m_scriptPath.isEmpty()) { - searchPaths.append(QString(RCC_PREFIX_PATH) + "resources/" + m_scriptPath); - searchPaths.append(Settings::getInstance()->getUserPath() + "resources/" + m_scriptPath); - // make sure to overwrite existing js stuff - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(QString(RCC_PREFIX_PATH) + Settings::getInstance()->getMods().at(i) + "/" + m_scriptPath); - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/" + m_scriptPath); - } + searchPaths = VirtualPaths::createSearchPath("resources/" + m_scriptPath); } return searchPaths; } diff --git a/resource_management/weaponmanager.cpp b/resource_management/weaponmanager.cpp index 1fa258efc..b4e486a09 100644 --- a/resource_management/weaponmanager.cpp +++ b/resource_management/weaponmanager.cpp @@ -1,5 +1,7 @@ #include +#include "coreengine/virtualpaths.h" + #include "resource_management/weaponmanager.h" #include "game/unit.h" @@ -53,11 +55,7 @@ void WeaponManager::loadAll() Interpreter* pInterpreter = Interpreter::getInstance(); QTemporaryDir tempDir = Settings::getInstance()->newTempDir(); QStringList data; - QFile file("resources/scripts/weapons/weapon_csv_import.txt"); - if (!file.exists()) - { - file.setFileName(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/scripts/weapons/weapon_csv_import.txt"); - } + QFile file(VirtualPaths::find("resources/scripts/weapons/weapon_csv_import.txt")); file.open(QIODevice::ReadOnly); QTextStream stream(&file); QString jsHeader = stream.readAll(); diff --git a/system/startup_messages.txt b/system/startup_messages.txt new file mode 100644 index 000000000..030311eee --- /dev/null +++ b/system/startup_messages.txt @@ -0,0 +1,340 @@ +No funny games found :( -> Installing some funny Viruses! +Remember Bug 1#: The calculation is correct, but why the hell is the output wrong? Maybe the Input is wrong... Maybe +What? I should work faster? Look at your PC even a snake is faster than your CPU +I know this Quest. Nothing can happen! Sorry we could not find their corps! +1+1=10 ... What you don't understand Binary Stuff -> I can't work with such stupid Users. +No good music found. No good videos found. There's nothing funny i can do here. +Even if you're eaten by a dragon, you still have two ways out. +I know what you did last summer... +Positioning GPS satellites... please stand by... +The volume goes to eleven! +The game will start when it is ready and not before! +You are the weakest link, goodbye! +/* You are not expected to understand this */ +Computer load this, computer load that, never a thank you... Rude gamers! +Now that's what I call a dead parrot +Loading errors, please wait... +Your soundcard sucks, disabling sound forever... +Relax, it's only ones and zeros! +No, this is not a silly message. +I still know what you did last summer... +Please stand by for an important announcement. +Your computer is running... You better go chase it. +Drawing beards onto your photographs... +Did you know that by reading this message you have wasted 5 seconds of your life? +Press any key... No! Not that one! +PI is exactly 3! Because I want to find out how world looks like where PI is exactly 3! +Freedom for wolves, ban the shepherds! +Your computer is now an official part of my world domination plan. Thank you! +There's nothing to see here, go ahead... +I don't care what you did last summer! +Ohh... I am loading too slowly? Ok, next time you'll load it yourself! +Searching for available information on dragons - Connecting to Wikipedia... +Warning: Don't try this at home! Why do you ignore this warning? +Are we there yet? Are we there yet? Are we there yet? +Oh this game sucks. It really game sucks! Did you know this game sucks! +Infiltrated your computer continuing to send your special videos to the CIA! Please Wait! +Press Any Key. I can't find the Any Key. +Why is it forbidden to use Emergency Exits in Germany? I mean they are called ""Not Exit"" +Let's play tic-tac-toe instead, I'll be X... +Coffee missing. Insert cup and press any key. +Clicking the mouse will not make the game load faster! +Knowledge is a weapon... I intend to be formidably armed. + I can't get no... Bug infection... +Press Crtl + Alt + Del now for an IQ test. Sorry IQ is to low to press those Keys. +Press any key to continue or other key to quit... +You did not call in sick just to play this game, now did you? +Backup not found: (A)bort, (R)etry, (G)et a beer. +Nuclear Power Plants are save as long as you don't try to use them to produce energy! +Your computer is your friend....Trust the Computer... +Counting to Infinity......Please wait... +This is not a drill. This is the Apocalypse. Please stay calm and exit the building. +Does a Table disappear always you leave a room. Because the modern physic says: it's possible! +Its not a bug but a feature. +Life? Don't talk to me about life! +Does a Table disappear always you leave a room. Because the modern physic says: it's possible! +Its not a bug but a feature. +Life? Don't talk to me about life! +Stop staring at this message or I will stop loading! +Loading 3D buffer... Not that one! +I've calculated your chance of survival, but I don't think you'll like it. +No more heroes available. Do you want to play as a monster? (Y/N) +Is their any sense in killing all those monsters? I mean the time you are back. They're back, too +Do you really want to start the game? Really? Are you really sure? +Gaming is about killing time, not killing people... +Ordering pizza online... I hope you like anchovies with pineapple! +Insert Disc 5... Oh, you don't have a Disc 5? Ok, filling harddisc with garbage... +Wasting energy, please wait... +Overclocking CPU: 3,0GHz...3,2GHz...3,6GHz... OOPS, I broke your CPU! +There is a light at the end of the tunnel, just pray it's not a train. +Please do not feed the dragons! +Not now! Can't you see I'm busy? Play something else. +Would you like to play a game of... world domination? +Insert coin to continue... +How can this task be delayed when i haven't even started working on it? +If the game does not start in five minutes... wait longer! +Randomizing constants... +Scroll down the list and choose your favourite silly message. I'm too lazy. +There's something written about a chance but I don't trust this game... +Checking mouse driver... Checking mouse's driving license... +Generating dead undead... Undead dead... uh... +Your skill in reading is increased by one point! +You'll get an adventure poqint32 for reading so much stupid messages. Use this poqint32 for improving your Stupidness! +Save the Earth... its the only planet with chocolate! +Why should we save the world? We didn't find out if we can survive without the world! +Operation failed (A)bort, (R)etry, (I)nfluence with large hammer? +The past temps us, the present confuses us, and the future frightens us. +Checking co2 emissions of your computer... Sorry, it's to high turning off your PC. +Are you still in the loading screen? You need a new computer! +Deleting all other games on the computer... You'll not need them in the next 5 seconds. +How long can you withstand dragon breath again? +Do you want to continue? (Y)es, (N)o, (M)aybe +Incredible... it's even worse than i thought it would be. +It seems that your mouse pointer is trying to move, (C)ancel or (A)llow? +Mommy, there's a monster in front of my screen! +Load it yourself, you slave driver! +You look rather silly staring at this screen... +Call 911 for support... +****, can't find this silly message file... +Are you sure you can still see the real world as real world? +Warning! your computer will self destruct in 5... 4... 3... 2... 1... +Don't you have better things to do then reading silly messages? +Who wants to live forever? Well... I wouldn't mind giving it a try! +Understanding is a three edged sword... our side, their side and the truth! +You're part of the game now... +There's a fine line between genius and insanity. I have erased this line. +ealth warning: you have been playing for 12 seconds... +Keep clicking until i say stop! +Two beer or not two beer... +If you have a slow pc, you are able to learn every silly message by heart... +Failed to load quests, I will now try to create some on my own... +Starting your mp3s... Argh, i can't listen to this anymore, go get some new songs! +Press y+m+q+enter+space with one hand to continue. +We don't have bugs, we have dragons! +This message is intended not to be funny. +I don't know what you're talking about, there is no game here... +I invented the 'hello world' program! +CPU says you should not start those boring office programs anymore. +What do you think I am doing? Loading the game? +Let's ride some trojan horses... I've found two in the left corner of your harddisc. +Killing some bugs, please wait... +Loading loadingscreen... +Hit any user to continue. +This game never has bugs. It just develops random features! +You just can't trust developers these days - they got even the silly messages bugged! +I don't have a solution, but I admire the problem! +There cannot be a crisis today, my schedule is already full. +I have a fix opinion, don't confuse me with facts! +The best way to create panic is to say: There is no reason to react panically. +If you want to continue roll a dice with excatly 21 numbers. +Did you feed your Mouse? Because i think it's dead! +If a chance to survive is excactly 1:1000000. Than you'll survive to 100%. Tell me if i'm right by finding it out! +I prefer a Sword instead of the well known Weapon Knowledge. In a RPG without Magic. +I believe i can fly. The Resulst can be seen, now. +I always await an Ambush, even when i'm asleep. +I'm not always right! But i'm never wrong! +It's so funny to kill them! It should be forbidden! IT'S FORBIDDEN!!! +Cheat-Mode detected! Installing Virus on Hard, Middle and Soft Disc. Please wait! +Braindetector activated, calibrating, now searching.........still searching......get a good grip of your mobile....still searching.......no brains found. +Did I not see you yesterday at the mall, with a grey jacket? No? O, than it was a rubbish bag after all! +What he want, I do not want ... What I want, he does not want ... What we want, is not allowed! +An Error has appeared while creating an Error Message. +"I hate when friends come over and ask, "Do you have a bathroom?" - "No, we shit outside." +A PC is only as clever as his User. +Access denied, please enter your ID again... +As a Computer, I find your faith in technology... amusing! +Eek! A mouse! Plug it out! Eek! It's full of bytes! +Funny Bugreport #22650: No sound while PC is burning! +Loading is booooring... +Loading MP3 playlist... +Loading silly messages... +Loading Sprite #559486753...Please wait! +Loading will continue after a short message from our Sponsor. +Monday morning Quest: Find my Coffee Mug in the Office! +Out of Money error ... Insert new projekt fundings! +Please turn off your monitor to continue. +Scanning Mail Folder... emty... not even Spam Mail! +Searching for Adult Filter... +Seaching for saved game... not found. Restarting game... +Spiderpig, Spiderpig ... +Stop staring at this message or I will stop loading. +The... no, A..., no, wait, sorry, that one sounded better in my head. +There's something written about a chance but I don´t trust this game... +There is a hole... in your mind. +There is too much CPU usage in zlib.dll! +Unloading silly messages, not silly enough! +Updating funny messages... +Uplink to ISS etablished, downloading weather forecast... +Uploading user fingerprints to NSA computer... +Use the mouse, Luke! +Video ram too small, switching to grid display... +Waiting some time... +We're working on the documentation ... +Warning! CPU temperature reaching critical... Shutting system down... +We apologize for the fault in loading screen. The responsible parties have been sacked. +We'll be right back after this commercial break. +What's that behind you? +What are you doing? Stop that! +When it's done! Got it? +When you are leaving, please close the door behind you. +Would you like to play a game of...World Domination? +Wrong CD Key... this Game will now be locked on this Computer for ever. +Yeah but no but yeah but no but yeah but no. +You are here: X +You are the 1.000.000th visitor! Congratulations! You won a box of tissues - not. +You won´t get this package if you can not ID yourself! +You really have to find a girlfriend whose name doesn´t end with .jpg! +Mysterious Strangers visits: 0 +I am a cute computer... really! +Never seen such a big... never mind... +Deleting all Celine Dion MP3s ... +Destroying brain cells... 15 percent... 50 percent... Duuh... +Cannot translate silly message into english. +Be sure to visit the gift shop on your way out. +Checking for 3d buffer ... Wait, not that one! +Activating coffee-machine... +Hehehe! You'll never guess what awaits you here! +Bacon is my favourite vegetable... +Do not include , use instead! +Cannot find Reality.sys… Universe halted. +Good. Out of the door. Line on the left. One cross each. Next. Crucifixion? +Here I am, brain the size of a planet, and they ask me to load files. +Man, what a mess on your harddisc... +Hidden DOS secret: Add bugs=off to your config.sys! +At some point, we'll have our own options.txt, son. One day... +Attention! This game can change your personality into evil... +I have the power of... of.. What's my line again? +Idea for a messagebox: 'This frame was properly rendered!' +Loading Bluescreen... +Sponsored by the Umbrella Corporation. +Don´t wake me up, I´m working... +It´s you again! Don´t you ever sleep? +No, this is not a silly message +Can I interest anyone in Fruit or Dessert? +our Oma is now Pwned by Studio II! +Detected System: Windows 3.11 - Switching Screen Resolution to 320 x 480 Pixels. +Hey Buddy! Need a cheap WiFi Cable? Only 100$! +Do you like Scary Movies? +My missus says that a spline is the mathmatical backbone of the game. +Two wrongs don't make a right, but three rights make a left! +I'm sensing a soul in search of answers... +Only silly coders need to optimize their code! +Uplink to ISS etablished, downloading weather forecast... +Good luck everyone - hope to see you again in the future! +A book can also be, a hat... +West of house, there is a small mailbox here. Exits are east and south. +Don't create multiple postings, use the edit button! +Do not disturb, system is disturbed already! +Don't push me. I'm doing my best, but your machine... tztztz... +... go to spriegel the schmitzel wertzen or something to that effect! +...Boldly going, where no one has ever gone before. At Least not recently. +Help! Your Keyboard is stuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk... +General Failure's fault. Not yours. +Deleting previously saved games... +earching for illegal Software ... just kidding! +Dude, where's my car? +Do you really want to start the game? Really? +Due to lack of system resources, entering slide-show mode... +Cheater detected. Loading bunnies... +Even if you die healthy, your dead. +Real Messages: Debugger doesn't work properly! Do you wish do Debug the Debugger with the Debugger? +Real Messages: Error Do you want to save your stuff or terminate without it? (Y)es ; (N)o. +e're going to be killed! Fascinating. +HOW MAY I SERVE YOU, INFERIOR BEING? +Didn't find a Dice for GETRANDOMNUMBER(). Please insert one into your CD Player. +Always doing the same is boring! Let's find out how a burning PC looks like! +The World is a plate and is carried by a Turtle on which stands three elephants. Everything else is wrong. +You don't have facebook??? Now, when you're officialy dead-> Dead people can't play! Stop loading... +Does a falling tree makes no Sound if there is nobody to here it fall? +Do you wish do spent all your money to the Project Owner? (Y)es ; No (disabled). +It should be fair. God go away with your human feelings. It's of course unfair. +"Ha finally i've got the last word."......"Nearly the last." +The part where you all shut up happens now. +My motto is that there are far too many women in the world to waste time with men. +You think i'm not funny? I can be not funny... +The bigger they are, the harder they fall! +Computers are useless. They can only give you answers. +Computers are like bikinis. They save people a lot of guesswork. +We have computers, and we may have other weapons of mass destruction. +That's what's cool about working with computers. They don't argue, they remember everything, and they don't drink all your beer. +If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside. +I've noticed lately that the paranoid fear of computers becoming intelligent and taking over the world has almost entirely disappeared from the common culture. Near as I can tell, this coincides with the release of MS-DOS. +The question of whether computers can think is like the question of whether submarines can swim. +It's ridiculous to live 100 years and only be able to remember 30 million bytes. You know, less than a compact disc. The human condition is really becoming more obsolete every minute. +Never trust a computer you can't throw out a window. +Hardware: The parts of a computer system that can be kicked. +Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. +The Internet? Is that thing still around? +Any fool can use a computer. Many do. +There are only two industries that refer to their customers as ‘users'. +Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. +That's the thing about people who think they hate computers. What they really hate is lousy programmers. +Don't worry if it doesn't work right. If everything did, you'd be out of a job. +Measuring programming progress by lines of code is like measuring aircraft building progress by weight. +Writing code has a place in the human hierarchy worth somewhere above grave robbing and beneath managing. +First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. +First, solve the problem. Then, write the code. +The best thing about a boolean is even if you are wrong, you are only off by a bit. +Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration. +There are only two kinds of programming languages: those people always bitch about and those nobody uses. +I think Microsoft named .Net so it wouldn't show up in a Unix directory listing. +There is no programming language–no matter how structured–that will prevent programmers from making bad programs. +Fifty years of programming language research, and we end up with C++? +In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg. +One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs. +Fine, Java MIGHT be a good example of what a programming language should be like. But Java applications are good examples of what applications SHOULDN'T be like. +If Java had true garbage collection, most programs would delete themselves upon execution. +Any code of your own that you haven't looked at for six or more months might as well have been written by someone else. +The first 90% of the code accounts for the first 10% of the development time. The remaining 10% of the code accounts for the other 90% of the development time. +If debugging is the process of removing bugs, then programming must be the process of putting them in. +I don't care if it works on your machine! We are not shipping your machine! +There are two ways to write error-free programs; only the third one works. +You can either have software quality or you can have pointer arithmetic, but you cannot have both at the same time. +Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. +Windows NT addresses 2 Gigabytes of RAM, which is more than any application will ever need. +Keyboard not found. Press < F1 > to RESUME. +Any sufficiently advanced bug is indistinguishable from a feature. +Beware of bugs in the above code; I have only proved it correct, not tried it. +bug, n: An elusive creature living in a program that makes it incorrect. The activity of ""debugging"", or removing bugs from a program, ends when people get tired of doing it, not when the bugs are removed. +Don't get suckered in by the comments— they can be terribly misleading. Debug only code +If the code and the comments disagree, then both are probably wrong. +Once you're done writing the code, never open it again unless you want to see how uncomprehensible and utterly ridiculous it really is. +The generation of random numbers is too important to be left to chance. +The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents. +Sometimes I believe compiler ignores all my comments + +You don't need luck. You need enough firepower. +This Game isn't about peace so "make war" +I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone. +The gap between theory and practice is not as wide in theory as it is in practice. +There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. +Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are–by definition–not smart enough to debug it. +If at first you don't succeed, call it version 1.0 +Rules of Optimization: Rule(1) : Don() 't do it. Rule 2 (for experts only): Don't do it yet. +Programming can be fun, so can cryptography; however they should not be combined. +Computers are good at following instructions, but not at reading your mind. +I just saw my life flash before my eyes and all I could see was a close tag… +Java: write once, debug everywhere. +All methodologies are based on fear. +Real programmers don't document. If it was hard to write, it should be hard to understand. +If we knew what we were doing, it wouldn't be called research, would it? +There are two kind of sysadmins: Paranoids and Losers. +We all know Linux is great... it does infinite loops in 5 seconds. +Comments lie. Code doesn't. +Exceed Funny Message File. Creating some new one's. +The Code is the Comment or believe in god. +This message was created by slavery and kids. +Error 404 no game found. Do your homework instead. +It isn't over until it's over! +We need to train tanks to talk. So we can get another Advance Wars game. +I invented a new word! Plagiarism! +Why don’t scientists trust atoms? Because they make up everything. +What did the 0 say to the 8? Nice belt! +Kanbei needs bases!!! +Andy: What's an airport? +Wait I can't refill myself? An APC +Damn those submerged submarines are blocking our way. A fighter pilot +Advance Wars is dead early 2021. Now we have a living zombie-tank. +Advance Wars 1 shoot that APC. SHOOOOT IT. Why? I said shoot it. It can create infinite supply. Only evil things can do that. +One day Flak will get indirect bombers and this day is near. +No more funny Messages found. Delete your Harddisk instead diff --git a/ui_reader/uifactory.cpp b/ui_reader/uifactory.cpp index ede0cb138..f4a9ab9b6 100644 --- a/ui_reader/uifactory.cpp +++ b/ui_reader/uifactory.cpp @@ -10,6 +10,7 @@ #include "3rd_party/oxygine-framework/oxygine/actor/ColorRectSprite.h" #include "coreengine/mainapp.h" +#include "coreengine/virtualpaths.h" #include "objects/base/label.h" #include "objects/base/checkbox.h" @@ -159,14 +160,7 @@ void UiFactory::createUi(QString uiXml, CreatedGui* pMenu) m_dropDownPlayer->init(); } m_creationCount = 0; - QStringList uiFiles; - // make sure to overwrite existing js stuff - for (qint32 i = Settings::getInstance()->getMods().size() - 1; i >= 0; --i) - { - uiFiles.append(Settings::getInstance()->getMods().at(i) + "/" + uiXml); - } - uiFiles.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/" + uiXml); - uiFiles.append("resources/" + uiXml); + QStringList uiFiles = VirtualPaths::createSearchPath("resources/" + uiXml); m_lastCoordinates.setRect(0, 0, 0, 0); for (const auto & uiFile : std::as_const(uiFiles)) { diff --git a/wiki/wikidatabase.cpp b/wiki/wikidatabase.cpp index b1ce49a8b..4de8beae4 100644 --- a/wiki/wikidatabase.cpp +++ b/wiki/wikidatabase.cpp @@ -1,5 +1,7 @@ #include +#include "coreengine/virtualpaths.h" + #include "wiki/wikidatabase.h" #include "wiki/fieldinfo.h" #include "wiki/defaultwikipage.h" @@ -106,13 +108,7 @@ void WikiDatabase::load() m_Entries.append(MemoryManagement::create(tr("Damage Table"), DAMAGE_TABLE_NAME, QStringList({tr("Others")}))); // load general wiki page - QStringList searchPaths; - for (qint32 i = 0; i < Settings::getInstance()->getMods().size(); i++) - { - searchPaths.append(Settings::getInstance()->getUserPath() + Settings::getInstance()->getMods().at(i) + "/scripts/wiki"); - } - searchPaths.append(Settings::getInstance()->getUserPath() + "resources/scripts/wiki"); - searchPaths.append(QString(oxygine::Resource::RCC_PREFIX_PATH) + "resources/scripts/wiki"); + QStringList searchPaths = VirtualPaths::createSearchPath("resources/scripts/wiki"); for (auto & path : searchPaths) { QStringList filter;