OpenClonk
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 
21 // *** C4ScenarioParameters
22 
24 {
25  if (!pComp->Name("Option")) { pComp->NameEnd(); pComp->excNotFound("Option"); }
28  pComp->Value(mkNamingAdapt( Value, "Value", 0));
29  pComp->NameEnd();
30 }
31 
33 {
34  // search option by value
35  for (const auto & Option : Options)
36  if (Option.Value == val)
37  return &Option;
38  return nullptr;
39 }
40 
42 {
43  if (idx >= Options.size()) return nullptr;
44  return &Options[idx];
45 }
46 
48 {
49  if (!pComp->Name("ParameterDef")) { pComp->NameEnd(); pComp->excNotFound("ParameterDef"); }
51  pComp->Value(mkNamingAdapt(mkParAdapt(Description, StdCompiler::RCT_All), "Description", StdCopyStrBuf()));
53  StdEnumEntry<ParameterType> ParTypeEntries[] =
54  {
55  { "Enumeration", SPDT_Enum },
56  { nullptr, SPDT_Enum }
57  };
58  pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(Type, ParTypeEntries), "Type", SPDT_Enum));
59  pComp->Value(mkNamingAdapt(Default, "Default", 0));
60  pComp->Value(mkNamingAdapt(LeagueValue, "LeagueValue", 0));
61  pComp->Value(mkNamingAdapt(mkParAdapt(Achievement, StdCompiler::RCT_Idtf), "Achievement", StdCopyStrBuf()));
62  pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(Options, StdCompiler::SEP_NONE), "Options"));
63  pComp->NameEnd();
64 }
65 
67 {
68  pComp->Value(mkSTLContainerAdapt(Parameters, StdCompiler::SEP_NONE));
69 }
70 
72 {
73  if (idx >= Parameters.size()) return nullptr;
74  return &Parameters[idx];
75 }
76 
78 {
79  // Load buffer, localize and parse
80  StdStrBuf Buf;
81  if (!hGroup.LoadEntryString(C4CFN_ScenarioParameterDefs,&Buf)) return false;
82  if (pLang) pLang->ReplaceStrings(Buf);
83  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, Buf, C4CFN_ScenarioParameterDefs))
84  { return false; }
85  return true;
86 }
87 
89 {
90  // register constants for all parameters in script engine
91 
92  // old-style: one constant per parameter
93  for (const auto & Parameter : Parameters)
94  {
95  StdStrBuf constant_name;
96  constant_name.Format("SCENPAR_%s", Parameter.GetID());
97  int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault());
98  ::ScriptEngine.RegisterGlobalConstant(constant_name.getData(), C4VInt(constant_value));
99  }
100 
101  // new-style: all constants in a proplist
102  auto scenpar = C4PropList::NewStatic(nullptr, nullptr, &Strings.P[P_SCENPAR]);
103  for (const auto & Parameter : Parameters)
104  {
105  int32_t constant_value = values.GetValueByID(Parameter.GetID(), Parameter.GetDefault());
106  scenpar->SetPropertyByS(Strings.RegString(StdStrBuf(Parameter.GetID())), C4VInt(constant_value));
107  }
108  scenpar->Freeze();
109  ::ScriptEngine.RegisterGlobalConstant("SCENPAR", C4Value(scenpar));
110 }
111 
113 {
114  Parameters.clear();
115 }
116 
118 {
119  // Merge lists and keep larger value
120  for (const auto & Parameter : other.Parameters)
121  {
122  auto j = Parameters.find(Parameter.first);
123  if (j != Parameters.end())
124  if (j->second >= Parameter.second)
125  continue; // existing value is same or larger - keep old
126  // update to new value from other list
127  Parameters[Parameter.first] = Parameter.second;
128  }
129 }
130 
131 int32_t C4ScenarioParameters::GetValueByID(const char *id, int32_t default_value) const
132 {
133  // return map value if name is in map. Otherwise, return default value.
134  auto i = Parameters.find(StdStrBuf(id));
135  if (i != Parameters.end()) return i->second; else return default_value;
136 }
137 
138 void C4ScenarioParameters::SetValue(const char *id, int32_t value, bool only_if_larger)
139 {
140  if (only_if_larger)
141  {
142  auto i = Parameters.find(StdStrBuf(id));
143  if (i != Parameters.end())
144  if (i->second >= value)
145  // could become smaller. don't set.
146  return;
147  }
148  // just update map
149  Parameters[StdCopyStrBuf(id)] = value;
150 }
151 
153 {
154  // Unfortunately, StdCompiler cannot save std::map yet
155  if (pComp->isDeserializer())
156  {
157  Parameters.clear();
158  if (pComp->hasNaming())
159  {
160  // load from INI
161  size_t name_count = pComp->NameCount();
162  for (size_t i=0; i<name_count; ++i)
163  {
164  int32_t v=0;
165  const char *name = pComp->GetNameByIndex(0); // always get name index 0, because names are removed after values have been extracted for them
166  StdCopyStrBuf sName(name);
167  if (!name) continue;
168  pComp->Value(mkNamingAdapt(v, sName.getData(), 0));
169  Parameters[sName] = v;
170  }
171  }
172  else
173  {
174  // load from binary
175  int32_t name_count=0;
176  pComp->Value(name_count);
177  for (int32_t i=0; i<name_count; ++i)
178  {
179  StdCopyStrBuf name; int32_t v;
180  pComp->Value(name);
181  pComp->Value(v);
182  Parameters[name] = v;
183  }
184  }
185  }
186  else
187  {
188  if (pComp->hasNaming())
189  {
190  // save to INI
191  for (auto & Parameter : Parameters)
192  pComp->Value(mkNamingAdapt(Parameter.second, Parameter.first.getData()));
193  }
194  else
195  {
196  // save to binary
197  int32_t name_count=Parameters.size();
198  pComp->Value(name_count);
199  for (auto & Parameter : Parameters)
200  {
201  pComp->Value(const_cast<StdCopyStrBuf &>(Parameter.first));
202  pComp->Value(Parameter.second);
203  }
204  }
205  }
206 }
207 
208 StdStrBuf C4ScenarioParameters::AddFilename2ID(const char *filename, const char *id)
209 {
210  // composes an ID string that contains both the relevant part of the filename and the ID
211  // we care for .oc* folders only
212  StdStrBuf sResult, sSource(filename, true), sPart;
214  size_t idx=0;
215  while (sSource.GetSection(idx++, &sPart, DirectorySeparator))
216  {
217  size_t len = sPart.getLength();
218  if (len > 4 && SEqual2NoCase(sPart.getPtr(len - 4), ".oc", 3))
219  {
220  // .oc* folders separated by underscores
221  sResult.Append(sPart.getData(), len - 4);
222  sResult.AppendChar('_');
223  }
224  }
225  sResult.Append(id);
226  return sResult;
227 }
#define C4CFN_ScenarioParameterDefs
Definition: C4Components.h:43
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
C4StringTable Strings
Definition: C4Globals.cpp:42
@ P_SCENPAR
C4Value C4VInt(int32_t i)
Definition: C4Value.h:239
#define DirectorySeparator
#define AltDirectorySeparator
bool SEqual2NoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:226
StdSTLContainerAdapt< C > mkSTLContainerAdapt(C &rTarget, StdCompiler::Sep eSep=StdCompiler::SEP_SEP)
Definition: StdAdaptors.h:713
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
Definition: StdAdaptors.h:795
void RegisterGlobalConstant(const char *szName, const C4Value &rValue)
Definition: C4Aul.cpp:123
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430
void ReplaceStrings(StdStrBuf &rBuf)
static C4PropListStatic * NewStatic(C4PropList *prototype, const C4PropListStatic *parent, C4String *key)
Definition: C4PropList.cpp:46
const Option * GetOptionByValue(int32_t val) const
const Option * GetOptionByIndex(size_t idx) const
void CompileFunc(StdCompiler *pComp)
void RegisterScriptConstants(const class C4ScenarioParameters &values)
const C4ScenarioParameterDef * GetParameterDefByIndex(size_t idx) const
bool Load(C4Group &hGroup, class C4LangStringTable *pLang)
void CompileFunc(StdCompiler *pComp)
void CompileFunc(StdCompiler *pComp)
int32_t GetValueByID(const char *id, int32_t default_value) const
void SetValue(const char *id, int32_t value, bool only_if_larger)
static StdStrBuf AddFilename2ID(const char *filename, const char *id)
void Merge(const C4ScenarioParameters &other)
C4String P[P_LAST]
C4String * RegString(StdStrBuf String)
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
void excNotFound(const char *szMessage,...)
Definition: StdCompiler.h:233
virtual bool isDeserializer()
Definition: StdCompiler.h:53
virtual int NameCount(const char *szName=nullptr)
Definition: StdCompiler.h:91
virtual const char * GetNameByIndex(size_t idx) const
Definition: StdCompiler.h:79
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
virtual bool hasNaming()
Definition: StdCompiler.h:58
const char * getData() const
Definition: StdBuf.h:442
void AppendChar(char cChar)
Definition: StdBuf.h:588
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
int ReplaceChar(char cOld, char cNew)
Definition: StdBuf.cpp:336
const char * getPtr(size_t i) const
Definition: StdBuf.h:448
size_t getLength() const
Definition: StdBuf.h:445
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
void CompileFunc(StdCompiler *pComp)