openclonk/src/landscape/C4ScenarioSection.cpp

159 lines
4.3 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#include "C4Include.h"
#include "landscape/C4Scenario.h"
#include "c4group/C4Components.h"
#include "script/C4ScriptHost.h"
// scenario sections
const char *C4ScenSect_Main = "main";
C4ScenarioSection::C4ScenarioSection(const char *szName)
{
// copy name
name.Copy(szName);
// zero fields
fModified = false;
pObjectScripts = nullptr;
// link into main list
pNext = Game.pScenarioSections;
Game.pScenarioSections = this;
}
C4ScenarioSection::~C4ScenarioSection()
{
// del following scenario sections
while (pNext)
{
C4ScenarioSection *pDel = pNext;
pNext = pNext->pNext;
pDel->pNext = nullptr;
delete pDel;
}
// del temp file
if (temp_filename.getData())
{
EraseItem(temp_filename.getData());
}
}
bool C4ScenarioSection::ScenarioLoad(const char *szFilename, bool is_temp_file)
{
// safety
if (filename.getData() || !szFilename) return false;
// store name
filename.Copy(szFilename);
if (is_temp_file)
{
// temp: Remember temp filename to be deleted on destruction
temp_filename.Copy(szFilename);
}
else
{
// non-temp: extract if it's not an open folder
if (Game.ScenarioFile.IsPacked()) if (!EnsureTempStore(true, true)) return false;
}
// load section object script
if (!SEqualNoCase(name.getData(), C4ScenSect_Main))
{
C4Group GrpSect, *pGrp;
if ((pGrp = GetGroupfile(GrpSect)) && pGrp->FindEntry(C4CFN_ScenarioObjectsScript))
{
pObjectScripts = new C4ScenarioObjectsScriptHost();
pObjectScripts->Reg2List(&::ScriptEngine);
pObjectScripts->Load(*pGrp, C4CFN_ScenarioObjectsScript, Config.General.LanguageEx, &::Game.ScenarioLangStringTable);
}
else
{
pObjectScripts = nullptr;
}
}
else
{
// Object script for main section
pObjectScripts = ::Game.pScenarioObjectsScript;
}
// donce, success
return true;
}
C4Group *C4ScenarioSection::GetGroupfile(C4Group &rGrp)
{
// check temp filename
if (temp_filename.getData())
{
if (rGrp.Open(temp_filename.getData())) return &rGrp;
else return nullptr;
}
// check filename within scenario
if (filename.getData())
{
if (rGrp.OpenAsChild(&Game.ScenarioFile, filename.getData())) return &rGrp;
else return nullptr;
}
// unmodified main section: return main group
if (SEqualNoCase(name.getData(), C4ScenSect_Main)) return &Game.ScenarioFile;
// failure
return nullptr;
}
bool C4ScenarioSection::EnsureTempStore(bool fExtractLandscape, bool fExtractObjects)
{
// if it's temp store already, don't do anything
if (temp_filename.getData()) return true;
// make temp filename
char *szTmp = const_cast<char *>(Config.AtTempPath(filename.getData() ? GetFilename(filename.getData()) : name.getData()));
MakeTempFilename(szTmp);
// main section: extract section files from main scenario group (create group as open dir)
if (!filename.getData())
{
if (!CreatePath(szTmp)) return false;
C4Group hGroup;
if (!hGroup.Open(szTmp, true)) { EraseItem(szTmp); return false; }
// extract all desired section files
Game.ScenarioFile.ResetSearch();
char fn[_MAX_FNAME+1]; *fn=0;
while (Game.ScenarioFile.FindNextEntry(C4FLS_Section, fn))
if (fExtractLandscape || !WildcardMatch(C4FLS_SectionLandscape, fn))
if (fExtractObjects || !WildcardMatch(C4FLS_SectionObjects, fn))
Game.ScenarioFile.ExtractEntry(fn, szTmp);
hGroup.Close();
}
else
{
// subsection: simply extract section from main group
if (!Game.ScenarioFile.ExtractEntry(filename.getData(), szTmp)) return false;
// delete undesired landscape/object files
if (!fExtractLandscape || !fExtractObjects)
{
C4Group hGroup;
if (hGroup.Open(filename.getData()))
{
if (!fExtractLandscape) hGroup.Delete(C4FLS_SectionLandscape);
if (!fExtractObjects) hGroup.Delete(C4FLS_SectionObjects);
}
}
}
// copy temp filename
temp_filename.Copy(szTmp);
// done, success
return true;
}