OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4ScenarioParameters.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 #include "C4Include.h"
18 #include "c4group/C4Components.h"
19 #include "script/C4Aul.h"
20 #include "graphics/C4FacetEx.h"
21 
22 
23 /* C4AchievementGraphics */
24 
26 {
27  // Load all graphics matching achievement filename and register them to map
28  char FileName[_MAX_FNAME];
29  File.ResetSearch();
30  while (File.FindNextEntry(C4CFN_Achievements, FileName))
31  {
32  C4FacetSurface *new_fct = new C4FacetSurface();
33  if (!new_fct->Load(File, FileName, C4FCT_Height, C4FCT_Full, false, 0))
34  {
35  delete new_fct;
36  LogF(LoadResStr("IDS_PRC_NOGFXFILE"), FileName, LoadResStr("IDS_ERR_NOFILE"));
37  return false;
38  }
39  // Register under filename excluding the leading "Achv" part. Delete any existing file with same name.
40  RemoveExtension(FileName);
41  int32_t id_offset = SCharPos('*', C4CFN_Achievements); assert(id_offset>=0);
42  StdCopyStrBuf sFileName(FileName + id_offset);
43  auto i = Graphics.find(sFileName);
44  if (i != Graphics.end()) delete i->second;
45  Graphics[sFileName] = new_fct;
46  }
47  // done. success no matter how many files were loaded.
48  return true;
49 }
50 
52 {
53  int32_t idNewGrp=0;
54  C4Group *pGrp = Files.FindEntry(C4CFN_Achievements, nullptr, &idNewGrp);
55  if (!pGrp) return true; // no achievement gfx. That's OK.
56  if (idNewGrp == idGrp) return true; // no update
57  idGrp = idNewGrp;
58  // OK, load from this group
59  return Init(*pGrp);
60 }
61 
63 {
64  for (auto i = Graphics.begin(); i != Graphics.end(); ++i)
65  delete i->second;
66  Graphics.clear();
67  idGrp = 0;
68 }
69 
71 {
72  auto i = Graphics.find(StdCopyStrBuf(name));
73  if (i != Graphics.end()) return i->second; else return nullptr;
74 }
75 
76 
77 
78 // *** C4ScenarioParameters
79 
81 {
82  if (!pComp->Name("Option")) { pComp->NameEnd(); pComp->excNotFound("Option"); }
85  pComp->Value(mkNamingAdapt( Value, "Value", 0));
86  pComp->NameEnd();
87 }
88 
90 {
91  // search option by value
92  for (auto i = Options.cbegin(); i != Options.cend(); ++i)
93  if (i->Value == val)
94  return &*i;
95  return nullptr;
96 }
97 
99 {
100  if (idx >= Options.size()) return nullptr;
101  return &Options[idx];
102 }
103 
105 {
106  if (!pComp->Name("ParameterDef")) { pComp->NameEnd(); pComp->excNotFound("ParameterDef"); }
108  pComp->Value(mkNamingAdapt(mkParAdapt(Description, StdCompiler::RCT_All), "Description", StdCopyStrBuf()));
110  StdEnumEntry<ParameterType> ParTypeEntries[] =
111  {
112  { "Enumeration", SPDT_Enum },
113  { nullptr, SPDT_Enum }
114  };
115  pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(Type, ParTypeEntries), "Type", SPDT_Enum));
116  pComp->Value(mkNamingAdapt(Default, "Default", 0));
117  pComp->Value(mkNamingAdapt(LeagueValue, "LeagueValue", 0));
118  pComp->Value(mkNamingAdapt(mkParAdapt(Achievement, StdCompiler::RCT_Idtf), "Achievement", StdCopyStrBuf()));
119  pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(Options, StdCompiler::SEP_NONE), "Options"));
120  pComp->NameEnd();
121 }
122 
124 {
125  pComp->Value(mkSTLContainerAdapt(Parameters, StdCompiler::SEP_NONE));
126 }
127 
129 {
130  if (idx >= Parameters.size()) return nullptr;
131  return &Parameters[idx];
132 }
133 
135 {
136  // Load buffer, localize and parse
137  StdStrBuf Buf;
138  if (!hGroup.LoadEntryString(C4CFN_ScenarioParameterDefs,&Buf)) return false;
139  if (pLang) pLang->ReplaceStrings(Buf);
140  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Buf, C4CFN_ScenarioParameterDefs))
141  { return false; }
142  return true;
143 }
144 
146 {
147  // register constants for all parameters in script engine
148 
149  // old-style: one constant per parameter
150  for (auto i = Parameters.cbegin(); i != Parameters.cend(); ++i)
151  {
152  StdStrBuf constant_name;
153  constant_name.Format("SCENPAR_%s", i->GetID());
154  int32_t constant_value = values.GetValueByID(i->GetID(), i->GetDefault());
155  ::ScriptEngine.RegisterGlobalConstant(constant_name.getData(), C4VInt(constant_value));
156  }
157 
158  // new-style: all constants in a proplist
159  auto scenpar = C4PropList::NewStatic(nullptr, nullptr, &Strings.P[P_SCENPAR]);
160  for (auto i = Parameters.cbegin(); i != Parameters.cend(); ++i)
161  {
162  int32_t constant_value = values.GetValueByID(i->GetID(), i->GetDefault());
163  scenpar->SetPropertyByS(Strings.RegString(StdStrBuf(i->GetID())), C4VInt(constant_value));
164  }
165  scenpar->Freeze();
166  ::ScriptEngine.RegisterGlobalConstant("SCENPAR", C4Value(scenpar));
167 }
168 
170 {
171  Parameters.clear();
172 }
173 
175 {
176  // Merge lists and keep larger value
177  for (auto i = other.Parameters.cbegin(); i != other.Parameters.cend(); ++i)
178  {
179  auto j = Parameters.find(i->first);
180  if (j != Parameters.end())
181  if (j->second >= i->second)
182  continue; // existing value is same or larger - keep old
183  // update to new value from other list
184  Parameters[i->first] = i->second;
185  }
186 }
187 
188 int32_t C4ScenarioParameters::GetValueByID(const char *id, int32_t default_value) const
189 {
190  // return map value if name is in map. Otherwise, return default value.
191  auto i = Parameters.find(StdStrBuf(id));
192  if (i != Parameters.end()) return i->second; else return default_value;
193 }
194 
195 void C4ScenarioParameters::SetValue(const char *id, int32_t value, bool only_if_larger)
196 {
197  if (only_if_larger)
198  {
199  auto i = Parameters.find(StdStrBuf(id));
200  if (i != Parameters.end())
201  if (i->second >= value)
202  // could become smaller. don't set.
203  return;
204  }
205  // just update map
206  Parameters[StdCopyStrBuf(id)] = value;
207 }
208 
210 {
211  // Unfortunately, StdCompiler cannot save std::map yet
212  if (pComp->isDeserializer())
213  {
214  Parameters.clear();
215  if (pComp->hasNaming())
216  {
217  // load from INI
218  size_t name_count = pComp->NameCount();
219  for (size_t i=0; i<name_count; ++i)
220  {
221  int32_t v=0;
222  const char *name = pComp->GetNameByIndex(0); // always get name index 0, because names are removed after values have been extracted for them
223  StdCopyStrBuf sName(name);
224  if (!name) continue;
225  pComp->Value(mkNamingAdapt(v, sName.getData(), 0));
226  Parameters[sName] = v;
227  }
228  }
229  else
230  {
231  // load from binary
232  int32_t name_count=0;
233  pComp->Value(name_count);
234  for (int32_t i=0; i<name_count; ++i)
235  {
236  StdCopyStrBuf name; int32_t v;
237  pComp->Value(name);
238  pComp->Value(v);
239  Parameters[name] = v;
240  }
241  }
242  }
243  else
244  {
245  if (pComp->hasNaming())
246  {
247  // save to INI
248  for (auto i = Parameters.begin(); i != Parameters.end(); ++i)
249  pComp->Value(mkNamingAdapt(i->second, i->first.getData()));
250  }
251  else
252  {
253  // save to binary
254  int32_t name_count=Parameters.size();
255  pComp->Value(name_count);
256  for (auto i = Parameters.begin(); i != Parameters.end(); ++i)
257  {
258  pComp->Value(const_cast<StdCopyStrBuf &>(i->first));
259  pComp->Value(i->second);
260  }
261  }
262  }
263 }
264 
265 StdStrBuf C4ScenarioParameters::AddFilename2ID(const char *filename, const char *id)
266 {
267  // composes an ID string that contains both the relevant part of the filename and the ID
268  // we care for .oc* folders only
269  StdStrBuf sResult, sSource(filename, true), sPart;
271  size_t idx=0;
272  while (sSource.GetSection(idx++, &sPart, DirectorySeparator))
273  {
274  size_t len = sPart.getLength();
275  if (len > 4 && SEqual2NoCase(sPart.getPtr(len - 4), ".oc", 3))
276  {
277  // .oc* folders separated by underscores
278  sResult.Append(sPart.getData(), len - 4);
279  sResult.AppendChar('_');
280  }
281  }
282  sResult.Append(id);
283  return sResult;
284 }
const char * getData() const
Definition: StdBuf.h:450
bool Load(C4Group &hGroup, class C4LangStringTable *pLang)
C4String P[P_LAST]
void RegisterGlobalConstant(const char *szName, const C4Value &rValue)
const C4ScenarioParameterDef * GetParameterDefByIndex(size_t idx) const
virtual bool hasNaming()
Definition: StdCompiler.h:68
const Option * GetOptionByIndex(size_t idx) const
Definition: StdAdaptors.h:760
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
bool Load(C4Group &hGroup, const char *szName, int iWdt, int iHgt, bool fNoErrIfNotFound, int iFlags)
Definition: C4FacetEx.cpp:78
C4String * RegString(StdStrBuf String)
void CompileFunc(StdCompiler *pComp)
C4Value C4VInt(int32_t i)
Definition: C4Value.h:242
const int C4FCT_Height
Definition: C4FacetEx.h:27
#define C4CFN_ScenarioParameterDefs
Definition: C4Components.h:43
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
virtual bool Name(const char *szName)
Definition: StdCompiler.h:87
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:93
void AppendChar(char cChar)
Definition: StdBuf.h:596
#define AltDirectorySeparator
static StdStrBuf AddFilename2ID(const char *filename, const char *id)
void CompileFunc(StdCompiler *pComp)
bool Init(C4Group &File)
virtual const char * GetNameByIndex(size_t idx) const
Definition: StdCompiler.h:89
C4StringTable Strings
Definition: C4Globals.cpp:42
C4Group * FindEntry(const char *szWildcard, int32_t *pPriority=nullptr, int32_t *pID=nullptr)
Definition: C4GroupSet.cpp:177
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:527
void excNotFound(const char *szMessage,...)
Definition: StdCompiler.h:242
void ReplaceStrings(StdStrBuf &rBuf)
#define _MAX_FNAME
static C4PropListStatic * NewStatic(C4PropList *prototype, const C4PropListStatic *parent, C4String *key)
Definition: C4PropList.cpp:70
void Value(const T &rStruct)
Definition: StdCompiler.h:170
void RemoveExtension(char *szFilename)
Definition: StdFile.cpp:316
int ReplaceChar(char cOld, char cNew)
Definition: StdBuf.cpp:343
#define C4CFN_Achievements
Definition: C4Components.h:90
virtual bool isDeserializer()
Definition: StdCompiler.h:63
const Option * GetOptionByValue(int32_t val) const
bool LoadEntryString(const char *szEntryName, StdStrBuf *Buf)
Definition: C4Group.cpp:1932
bool FindNextEntry(const char *szWildCard, StdStrBuf *sFileName=nullptr, size_t *iSize=nullptr, bool fStartAtFilename=false)
Definition: C4Group.cpp:1780
void Merge(const C4ScenarioParameters &other)
StdSTLContainerAdapt< C > mkSTLContainerAdapt(C &rTarget, StdCompiler::Sep eSep=StdCompiler::SEP_SEP)
Definition: StdAdaptors.h:679
void CompileFunc(StdCompiler *pComp)
C4FacetSurface * FindByName(const char *name) const
virtual int NameCount(const char *szName=nullptr)
Definition: StdCompiler.h:101
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:190
const char * getPtr(size_t i) const
Definition: StdBuf.h:456
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:456
size_t getLength() const
Definition: StdBuf.h:453
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1013
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:203
void CompileFunc(StdCompiler *pComp)
void RegisterScriptConstants(const class C4ScenarioParameters &values)
#define DirectorySeparator
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:253
const int C4FCT_Full
Definition: C4FacetEx.h:26
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:88
int32_t GetValueByID(const char *id, int32_t default_value) const
void SetValue(const char *id, int32_t value, bool only_if_larger)