1 /////////////////////////////////////////
2 //
3 //             OpenLieroX
4 //
5 // code under LGPL, based on JasonBs work,
6 // enhanced by Dark Charlie and Albert Zeyer
7 //
8 //
9 /////////////////////////////////////////
10 
11 #include "CScriptableVars.h"
12 #include "Debug.h"
13 #include "StringUtils.h"
14 
15 #include <sstream>
16 
17 
18 
19 const char * GameInfoGroupDescriptions[][2] =
20 {
21 {"General", "General game options"},
22 {"Advanced", "Advanced game options"},
23 {"Scores", "Scoreboard related game options"},
24 {"Weapons", "Weapons and game physics related game options"},
25 {"Bonuses", "Bonuses related game options"},
26 {"Other", "Other game options"},
27 {"", ""}, // GIG_GameModeSpecific_Start - dummy value
28 {"Tag", "Tag gamemode settings"},
29 {"Hide and Seek", "Hide and Seek gamemode settings"},
30 {"Capture The Flag", "Capture The Flag gamemode settings"},
31 {"Race", "Race gamemode settings"},
32 };
33 
34 static_assert( sizeof(GameInfoGroupDescriptions) / (sizeof(char*) * 2) == GIG_Size, "GIG_desc__sizecheck" );
35 
36 
AdvancedLevelDescription(AdvancedLevel l)37 std::string AdvancedLevelDescription(AdvancedLevel l) {
38 	switch(l) {
39 		case ALT_Basic: return "Basic settings.";
40 		case ALT_Advanced: return "Advanced settings. For more professional players.";
41 		case ALT_VeryAdvanced: return "Very advanced settings. For people who like to try out special unusual settings.";
42 		case ALT_Dev: return "Development features. Some of them can be unstable or are incomplete yet. Please report errors if you see any.";
43 		case ALT_DevKnownUnstable: return "Unstable development features. These features are known to be unstable. You have been warned.";
44 		case ALT_OnlyViaConfig: return "ONLY VIA CONFIG.";
45 		case __AdvancedLevelType_Count: return "INVALID BOTTOM ADVANCED LEVEL MARKER";
46 	}
47 
48 	return "INVALID ADVANCED LEVEL VAR";
49 }
50 
AdvancedLevelShortDescription(AdvancedLevel l)51 std::string AdvancedLevelShortDescription(AdvancedLevel l) {
52 	switch(l) {
53 		case ALT_Basic: return "Basic";
54 		case ALT_Advanced: return "Advanced";
55 		case ALT_VeryAdvanced: return "Very advanced";
56 		case ALT_Dev: return "Development";
57 		case ALT_DevKnownUnstable: return "Unstable";
58 		case ALT_OnlyViaConfig: return "CONFIG.";
59 		case __AdvancedLevelType_Count: return "INVALID";
60 	}
61 
62 	return "INVALID";
63 }
64 
65 
66 
toString() const67 std::string ScriptVar_t::toString() const {
68 	switch(type) {
69 		case SVT_BOOL: return to_string(b);
70 		case SVT_INT: return to_string(i);
71 		case SVT_FLOAT: return to_string(f);
72 		case SVT_STRING: return s;
73 		case SVT_COLOR: return ColToHex(c);
74 		default: assert(false); return "";
75 	}
76 }
77 
fromString(const std::string & str)78 bool ScriptVar_t::fromString( const std::string & str )
79 {
80 	switch(type) {
81 		case SVT_BOOL: b = from_string<bool>(str); break;
82 		case SVT_INT: i = from_string<int>(str); break;
83 		case SVT_FLOAT: f = from_string<float>(str); break;
84 		case SVT_STRING: s = str; break;
85 		case SVT_COLOR: c = StrToCol(str); break;
86 		default: assert(false); return false;
87 	}
88 	return true;
89 }
90 
toString() const91 std::string ScriptVarPtr_t::toString() const
92 {
93 	switch(type) {
94 		case SVT_BOOL: return to_string(*b);
95 		case SVT_INT: return to_string(*i);
96 		case SVT_FLOAT: return to_string(*f);
97 		case SVT_STRING: return *s;
98 		case SVT_COLOR: return ColToHex(*cl);
99 		case SVT_DYNAMIC: return dynVar->asScriptVar().toString();
100 		case SVT_CALLBACK: return "callback(0x" + hex((long)cb) + ")";
101 		default: assert(false); return "";
102 	}
103 }
104 
fromString(const std::string & _str) const105 bool ScriptVarPtr_t::fromString( const std::string & _str) const {
106 	std::string str = _str; TrimSpaces(str);
107 
108 	switch(type) {
109 		case SVT_BOOL: *b = from_string<bool>(str); break;
110 		case SVT_INT:
111 			// TODO: why is that here and not in ScriptVar_t::fromString ?
112 			if (isUnsigned && str.size() == 0)
113 				*i = -1; // Infinite
114 			else
115 				*i = from_string<int>(str);
116 		break;
117 		case SVT_FLOAT:
118 			// TODO: why is that here and not in ScriptVar_t::fromString ?
119 			if (isUnsigned && str.size() == 0)
120 				*f = -1;
121 			else
122 				*f = from_string<float>(str);
123 		break;
124 		case SVT_STRING: *s = str; break;
125 		case SVT_COLOR: *cl = StrToCol(str); break;
126 		case SVT_DYNAMIC: {
127 			ScriptVar_t var = dynVar->asScriptVar();
128 			if(!var.fromString(str)) return false;
129 			dynVar->fromScriptVar(var);
130 			return true;
131 		}
132 		default: assert(false); return false;
133 	}
134 	return true;
135 }
136 
setDefault() const137 void ScriptVarPtr_t::setDefault() const {
138 	switch(type) {
139 		case SVT_BOOL: *b = bdef; break;
140 		case SVT_INT: *i = idef; break;
141 		case SVT_FLOAT: *f = fdef; break;
142 		case SVT_STRING: *s = sdef; break;
143 		case SVT_COLOR: *cl = Color(cldef); break;
144 		case SVT_DYNAMIC: {
145 			// TODO: this could be simpler if the default values would be just a ScriptVar_t
146 			switch(dynVar->type()) {
147 				case SVT_BOOL: ((DynamicVar<bool>*)dynVar)->set(bdef); break;
148 				case SVT_INT: ((DynamicVar<int>*)dynVar)->set(idef); break;
149 				case SVT_FLOAT: ((DynamicVar<float>*)dynVar)->set(fdef); break;
150 				case SVT_STRING: ((DynamicVar<std::string>*)dynVar)->set(sdef); break;
151 				case SVT_COLOR: ((DynamicVar<Color>*)dynVar)->set(cldef); break;
152 				default: assert(false);
153 			}
154 			break;
155 		}
156 		default: assert(false);
157 	}
158 
159 }
160 
161 
162 CScriptableVars * CScriptableVars::m_instance = NULL;
163 
Init()164 CScriptableVars & CScriptableVars::Init()
165 {
166 	if( m_instance == NULL )
167 		m_instance = new CScriptableVars;
168 	return *m_instance;
169 }
170 
DeInit()171 void CScriptableVars::DeInit()
172 {
173 	if( CScriptableVars::m_instance != NULL )
174 	{
175 		delete CScriptableVars::m_instance;
176 		CScriptableVars::m_instance = NULL;
177 	}
178 }
179 
StripClassName(const std::string & c)180 std::string CScriptableVars::StripClassName( const std::string & c )
181 {
182 	std::string ret(c);
183 	if( ret.rfind(".") != std::string::npos )	// Leave only last part of name
184 		ret = ret.substr( ret.rfind(".") + 1 );
185 	return ret;
186 }
187 
GetVar(const std::string & name)188 RegisteredVar* CScriptableVars::GetVar( const std::string & name )
189 {
190 	Init();
191 	VarMap::iterator it = m_instance->m_vars.find(name);
192 	if(it != m_instance->m_vars.end()) return &it->second;
193 	return NULL;
194 }
195 
196 
GetVar(const std::string & name,ScriptVarType_t type)197 RegisteredVar* CScriptableVars::GetVar( const std::string & name, ScriptVarType_t type )
198 {
199 	RegisteredVar* var = GetVar(name);
200 	if(!var) return NULL;
201 	if(var->var.type != type) return NULL;
202 	return var;
203 }
204 
DeRegisterVars(const std::string & base)205 void CScriptableVars::DeRegisterVars( const std::string & base )
206 {
207 	if( ! m_instance )
208 	{
209 		errors << "CScriptableVars::DeRegisterVars() - error, deregistering vars \"" << base << "\" after CScriptableVars were destroyed" << endl;
210 		return;
211 	}
212 	Init();
213 	VarMap::iterator upper = m_instance->m_vars.upper_bound(base + ".\177\177\177");
214 	for( VarMap::iterator it = m_instance->m_vars.lower_bound(base + "."); it != upper;  )
215 	{
216 		VarMap::iterator cp = it; ++it;
217 		m_instance->m_vars.erase( cp );
218 	}
219 }
220 
DumpVars()221 std::string CScriptableVars::DumpVars()
222 {
223 	Init();
224 	std::ostringstream ret;
225 	for( VarMap :: iterator i = m_instance->m_vars.begin();
226 			i != m_instance->m_vars.end(); i++ )
227 	{
228 		ret << i->first + ": ";
229 		switch( i->second.var.type == SVT_DYNAMIC ? i->second.var.dynVar->type() : i->second.var.type )
230 		{
231 			case SVT_BOOL: ret << "bool: "; break;
232 			case SVT_INT: ret << "int: "; break;
233 			case SVT_FLOAT: ret << "float: "; break;
234 			case SVT_STRING: ret << "string: "; break;
235 			case SVT_COLOR: ret << "color: "; break;
236 			case SVT_CALLBACK: ret << "callback: "; break;
237 			default: assert(false);
238 		}
239 		ret << i->second.var.toString();
240 		ret << "\n";
241 	}
242 	return ret.str();
243 }
244 
SetVarByString(const ScriptVarPtr_t & var,const std::string & str)245 void CScriptableVars::SetVarByString(const ScriptVarPtr_t& var, const std::string& str)
246 {
247 	var.fromString(str);
248 }
249 
operator <<(std::ostream & o,const ScriptVar_t & svt)250 std::ostream& operator<< (std::ostream& o, const ScriptVar_t& svt)
251 {
252 	o << svt.toString();
253 	return o;
254 }
255 
operator <<(std::ostream & o,const ScriptVarPtr_t & svt)256 std::ostream& operator<< (std::ostream& o, const ScriptVarPtr_t& svt)
257 {
258 	o << svt.toString();
259 	return o;
260 }
261