forked from Mirrors/openclonk
272 lines
8.3 KiB
C++
272 lines
8.3 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2013, 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 "C4ScenarioParameters.h"
|
|
#include "C4Components.h"
|
|
#include "C4Aul.h"
|
|
#include "C4FacetEx.h"
|
|
|
|
|
|
/* C4AchievementGraphics */
|
|
|
|
bool C4AchievementGraphics::Init(C4Group &File)
|
|
{
|
|
// Load all graphics matching achievement filename and register them to map
|
|
char FileName[_MAX_FNAME];
|
|
File.ResetSearch();
|
|
while (File.FindNextEntry(C4CFN_Achievements, FileName))
|
|
{
|
|
C4FacetSurface *new_fct = new C4FacetSurface();
|
|
if (!new_fct->Load(File, FileName, C4FCT_Height, C4FCT_Full))
|
|
{
|
|
delete new_fct;
|
|
LogF(LoadResStr("IDS_PRC_NOGFXFILE"), FileName, LoadResStr("IDS_ERR_NOFILE"));
|
|
return false;
|
|
}
|
|
// Register under filename excluding the leading "Achv" part. Delete any existing file with same name.
|
|
RemoveExtension(FileName);
|
|
int32_t id_offset = SCharPos('*', C4CFN_Achievements); assert(id_offset>=0);
|
|
StdCopyStrBuf sFileName(FileName + id_offset);
|
|
auto i = Graphics.find(sFileName);
|
|
if (i != Graphics.end()) delete i->second;
|
|
Graphics[sFileName] = new_fct;
|
|
}
|
|
// done. success no matter how many files were loaded.
|
|
return true;
|
|
}
|
|
|
|
bool C4AchievementGraphics::Init(C4GroupSet &Files)
|
|
{
|
|
int32_t idNewGrp=0;
|
|
C4Group *pGrp = Files.FindEntry(C4CFN_Achievements, NULL, &idNewGrp);
|
|
if (!pGrp) return true; // no achievement gfx. That's OK.
|
|
if (idNewGrp == idGrp) return true; // no update
|
|
idGrp = idNewGrp;
|
|
// OK, load from this group
|
|
return Init(*pGrp);
|
|
}
|
|
|
|
void C4AchievementGraphics::Clear()
|
|
{
|
|
for (auto i = Graphics.begin(); i != Graphics.end(); ++i)
|
|
delete i->second;
|
|
Graphics.clear();
|
|
idGrp = 0;
|
|
}
|
|
|
|
C4FacetSurface *C4AchievementGraphics::FindByName(const char *name) const
|
|
{
|
|
auto i = Graphics.find(StdCopyStrBuf(name));
|
|
if (i != Graphics.end()) return i->second; else return NULL;
|
|
}
|
|
|
|
|
|
|
|
// *** C4ScenarioParameters
|
|
|
|
void C4ScenarioParameterDef::Option::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
if (!pComp->Name("Option")) { pComp->NameEnd(); pComp->excNotFound("Option"); }
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(Name, StdCompiler::RCT_All), "Name", StdCopyStrBuf()));
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(Description, StdCompiler::RCT_All), "Description", StdCopyStrBuf()));
|
|
pComp->Value(mkNamingAdapt( Value, "Value", 0));
|
|
pComp->NameEnd();
|
|
}
|
|
|
|
const C4ScenarioParameterDef::Option *C4ScenarioParameterDef::GetOptionByValue(int32_t val) const
|
|
{
|
|
// search option by value
|
|
for (auto i = Options.cbegin(); i != Options.cend(); ++i)
|
|
if (i->Value == val)
|
|
return &*i;
|
|
return NULL;
|
|
}
|
|
|
|
const C4ScenarioParameterDef::Option *C4ScenarioParameterDef::GetOptionByIndex(size_t idx) const
|
|
{
|
|
if (idx >= Options.size()) return NULL;
|
|
return &Options[idx];
|
|
}
|
|
|
|
void C4ScenarioParameterDef::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
if (!pComp->Name("ParameterDef")) { pComp->NameEnd(); pComp->excNotFound("ParameterDef"); }
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(Name, StdCompiler::RCT_All), "Name", StdCopyStrBuf()));
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(Description, StdCompiler::RCT_All), "Description", StdCopyStrBuf()));
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(ID, StdCompiler::RCT_Idtf), "ID", StdCopyStrBuf()));
|
|
StdEnumEntry<ParameterType> ParTypeEntries[] =
|
|
{
|
|
{ "Enumeration", SPDT_Enum },
|
|
{ NULL, SPDT_Enum }
|
|
};
|
|
pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(Type, ParTypeEntries), "Type", SPDT_Enum));
|
|
pComp->Value(mkNamingAdapt(Default, "Default", 0));
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(Achievement, StdCompiler::RCT_Idtf), "Achievement", StdCopyStrBuf()));
|
|
pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(Options, StdCompiler::SEP_NONE), "Options"));
|
|
pComp->NameEnd();
|
|
}
|
|
|
|
void C4ScenarioParameterDefs::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkSTLContainerAdapt(Parameters, StdCompiler::SEP_NONE));
|
|
}
|
|
|
|
const C4ScenarioParameterDef *C4ScenarioParameterDefs::GetParameterDefByIndex(size_t idx) const
|
|
{
|
|
if (idx >= Parameters.size()) return NULL;
|
|
return &Parameters[idx];
|
|
}
|
|
|
|
bool C4ScenarioParameterDefs::Load(C4Group &hGroup, C4LangStringTable *pLang)
|
|
{
|
|
// Load buffer, localize and parse
|
|
StdStrBuf Buf;
|
|
if (!hGroup.LoadEntryString(C4CFN_ScenarioParameterDefs,&Buf)) return false;
|
|
if (pLang) pLang->ReplaceStrings(Buf);
|
|
if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Buf, C4CFN_ScenarioCore))
|
|
{ return false; }
|
|
return true;
|
|
}
|
|
|
|
void C4ScenarioParameterDefs::RegisterScriptConstants(const C4ScenarioParameters &values)
|
|
{
|
|
// register constants for all parameters in script engine
|
|
for (auto i = Parameters.cbegin(); i != Parameters.cend(); ++i)
|
|
{
|
|
StdStrBuf constant_name;
|
|
constant_name.Format("SCENPAR_%s", i->GetID());
|
|
int32_t constant_value = values.GetValueByID(i->GetID(), i->GetDefault());
|
|
::ScriptEngine.RegisterGlobalConstant(constant_name.getData(), C4VInt(constant_value));
|
|
}
|
|
}
|
|
|
|
void C4ScenarioParameters::Clear()
|
|
{
|
|
Parameters.clear();
|
|
}
|
|
|
|
void C4ScenarioParameters::Merge(const C4ScenarioParameters &other)
|
|
{
|
|
// Merge lists and keep larger value
|
|
for (auto i = other.Parameters.cbegin(); i != other.Parameters.cend(); ++i)
|
|
{
|
|
auto j = Parameters.find(i->first);
|
|
if (j != Parameters.end())
|
|
if (j->second >= i->second)
|
|
continue; // existing value is same or larger - keep old
|
|
// update to new value from other list
|
|
Parameters[i->first] = i->second;
|
|
}
|
|
}
|
|
|
|
int32_t C4ScenarioParameters::GetValueByID(const char *id, int32_t default_value) const
|
|
{
|
|
// return map value if name is in map. Otherwise, return default value.
|
|
auto i = Parameters.find(StdStrBuf(id));
|
|
if (i != Parameters.end()) return i->second; else return default_value;
|
|
}
|
|
|
|
void C4ScenarioParameters::SetValue(const char *id, int32_t value, bool only_if_larger)
|
|
{
|
|
if (only_if_larger)
|
|
{
|
|
auto i = Parameters.find(StdStrBuf(id));
|
|
if (i != Parameters.end())
|
|
if (i->second >= value)
|
|
// could become smaller. don't set.
|
|
return;
|
|
}
|
|
// just update map
|
|
Parameters[StdCopyStrBuf(id)] = value;
|
|
}
|
|
|
|
void C4ScenarioParameters::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
// Unfortunately, StdCompiler cannot save std::map yet
|
|
if (pComp->isCompiler())
|
|
{
|
|
Parameters.clear();
|
|
if (pComp->hasNaming())
|
|
{
|
|
// load from INI
|
|
size_t name_count = pComp->NameCount();
|
|
for (size_t i=0; i<name_count; ++i)
|
|
{
|
|
int32_t v=0;
|
|
const char *name = pComp->GetNameByIndex(0); // always get name index 0, because names are removed after values have been extracted for them
|
|
StdCopyStrBuf sName(name);
|
|
if (!name) continue;
|
|
pComp->Value(mkNamingAdapt(v, sName.getData(), 0));
|
|
Parameters[sName] = v;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// load from binary
|
|
int32_t name_count=0;
|
|
pComp->Value(name_count);
|
|
for (int32_t i=0; i<name_count; ++i)
|
|
{
|
|
StdCopyStrBuf name; int32_t v;
|
|
pComp->Value(name);
|
|
pComp->Value(v);
|
|
Parameters[name] = v;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pComp->hasNaming())
|
|
{
|
|
// save to INI
|
|
for (auto i = Parameters.begin(); i != Parameters.end(); ++i)
|
|
pComp->Value(mkNamingAdapt(i->second, i->first.getData()));
|
|
}
|
|
else
|
|
{
|
|
// save to binary
|
|
int32_t name_count=Parameters.size();
|
|
pComp->Value(name_count);
|
|
for (auto i = Parameters.begin(); i != Parameters.end(); ++i)
|
|
{
|
|
pComp->Value(const_cast<StdCopyStrBuf &>(i->first));
|
|
pComp->Value(i->second);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StdStrBuf C4ScenarioParameters::AddFilename2ID(const char *filename, const char *id)
|
|
{
|
|
// composes an ID string that contains both the relevant part of the filename and the ID
|
|
// we care for .oc* folders only
|
|
StdStrBuf sResult, sSource(filename, true), sPart;
|
|
sSource.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
|
|
size_t idx=0;
|
|
while (sSource.GetSection(idx++, &sPart, DirectorySeparator))
|
|
{
|
|
size_t len = sPart.getLength();
|
|
if (len > 4 && !strnicmp(sPart.getPtr(len - 4), ".oc", 3))
|
|
{
|
|
// .oc* folders separated by underscores
|
|
sResult.Append(sPart.getData(), len - 4);
|
|
sResult.AppendChar('_');
|
|
}
|
|
}
|
|
sResult.Append(id);
|
|
return sResult;
|
|
}
|