1 /*
2  *  FeatureList.h
3  *  OpenLieroX
4  *
5  *  Created by Albert Zeyer on 22.12.08.
6  *	code under LGPL
7  *
8  */
9 
10 #ifndef __FEATURELIST_H__
11 #define __FEATURELIST_H__
12 
13 #include <string>
14 #include <set>
15 #include <map>
16 #include "Iterator.h"
17 #include "CScriptableVars.h"
18 #include "Version.h"
19 
20 class GameServer;
21 
22 struct Feature {
23 	std::string name; // for config, network and other identification
24 	std::string humanReadableName;
25 	std::string description;
26 	typedef ScriptVarType_t VarType;
27 	typedef ScriptVar_t Var;
28 	VarType valueType; // for example: float for gamespeed, bool for ropelenchange
29 	Var unsetValue; // if the server does not provide this; for example: gamespeed=1; should always be like the behaviour without the feature to keep backward compatibility
30 	Var defaultValue; // for config, if not set before, in most cases the same as unsetValue
31 
32 	Version minVersion; // min supported version (<=beta8 is not updated automatically by the system)
33 	// Old clients are kicked if feature version is greater that client version, no matter if feature is server-sided or optinal
34 
35 	GameInfoGroup group;	// For grouping similar options in GUI
36 
37 	AdvancedLevel advancedLevel;
38 
39 	// TODO: make special type VarRange (which holds these hasmin/hasmax/min/max/signed)
40 	// TODO: move that to ScriptVarType_t
41 	Var minValue; // Min and max values are used in GUI to make sliders (only for float/int)
42 	Var maxValue; // Min and max values are used in GUI to make sliders (only for float/int)
43 	bool unsignedValue; // If the value is unsigned - ints and floats only
44 
45 	bool serverSideOnly; // if true, all the following is just ignored
46 	bool optionalForClient; // Optional client-sided feature, like vision cone drawn for seekers, or SuicideDecreasesScore which required for precise damage calculation in scoreboard
47 
48 	bool unsetIfOlderClients; // This flag will reset feature to unset value if an older client is connected
49 
50 	typedef Var (GameServer::*GetValueFunction)( const Var& preset );
51 	GetValueFunction getValueFct; // if set, it uses the return value for hostGet
52 
53 	bool SET; // Flag that marks end of global features list
54 
FeatureFeature55 	Feature() : SET(false) {}
UnsetFeature56 	static Feature Unset() { return Feature(); }
57 
58 	Feature(const std::string& n, const std::string& hn, const std::string& desc, bool unset, bool def,
59 				Version ver, GameInfoGroup g = GIG_Invalid, AdvancedLevel l = ALT_Basic, bool ssdo = false, bool opt = false,
60 				bool u = false, GetValueFunction f = NULL)
nameFeature61 	: name(n), humanReadableName(hn), description(desc), valueType(SVT_BOOL), unsetValue(Var(unset)), defaultValue(Var(def)),
62 		minVersion(ver), group(g), advancedLevel(l), serverSideOnly(ssdo), optionalForClient(opt),
63 		unsetIfOlderClients(u), getValueFct(f), SET(true) {}
64 
65 	Feature(const std::string& n, const std::string& hn, const std::string& desc, int unset, int def,
66 				Version ver, GameInfoGroup g = GIG_Invalid, AdvancedLevel l = ALT_Basic, int minval = 0, int maxval = 0, bool ssdo = false, bool opt = false,
67 				bool u = false, bool unsig = false, GetValueFunction f = NULL)
nameFeature68 	: name(n), humanReadableName(hn), description(desc), valueType(SVT_INT), unsetValue(Var(unset)), defaultValue(Var(def)),
69 		minVersion(ver), group(g), advancedLevel(l), minValue(minval), maxValue(maxval), unsignedValue(unsig), serverSideOnly(ssdo),
70 		optionalForClient(opt), unsetIfOlderClients(u), getValueFct(f), SET(true) {}
71 
72 	Feature(const std::string& n, const std::string& hn, const std::string& desc, float unset, float def,
73 				Version ver, GameInfoGroup g = GIG_Invalid, AdvancedLevel l = ALT_Basic, float minval = 0.0f, float maxval = 0.0f, bool ssdo = false, bool opt = false,
74 				bool u = false, bool unsig = false, GetValueFunction f = NULL)
nameFeature75 	: name(n), humanReadableName(hn), description(desc), valueType(SVT_FLOAT), unsetValue(Var(unset)), defaultValue(Var(def)),
76 		minVersion(ver), group(g), advancedLevel(l), minValue(minval), maxValue(maxval), unsignedValue(unsig), serverSideOnly(ssdo),
77 		optionalForClient(opt), unsetIfOlderClients(u), getValueFct(f), SET(true) {}
78 
79 	Feature(const std::string& n, const std::string& hn, const std::string& desc, const char * unset, const char * def,
80 				Version ver, GameInfoGroup g = GIG_Invalid, AdvancedLevel l = ALT_Basic, bool ssdo = false, bool opt = false,
81 				bool u = false, GetValueFunction f = NULL)
nameFeature82 	: name(n), humanReadableName(hn), description(desc), valueType(SVT_STRING), unsetValue(Var(unset)), defaultValue(Var(def)),
83 		minVersion(ver), group(g), advancedLevel(l), serverSideOnly(ssdo), optionalForClient(opt),
84 		unsetIfOlderClients(u), getValueFct(f), SET(true) {}
85 
86 };
87 
88 extern Feature featureArray[];
featureArrayLen()89 inline int featureArrayLen() { int l = 0; for(Feature* f = featureArray; f->SET; ++f) ++l; return l; }
clientSideFeatureCount()90 inline int clientSideFeatureCount() { int l = 0; for(Feature* f = featureArray; f->SET; ++f) if(!f->serverSideOnly) ++l; return l; }
91 Feature* featureByName(const std::string& name);
92 
93 // Indexes of features in featureArray
94 // These indexes are only for local game use, not for network! (name is used there)
95 // (I am not that happy with this solution right now, I would like to put both these indexes together
96 //  with the actual declaration of the Feature. Though I don't know a way how to put both things together
97 //  in the header file.)
98 // WARNING: Keep this always synchronised with featureArray!
99 enum FeatureIndex {
100 	FT_GameSpeed = 0,
101 	FT_GameSpeedOnlyForProjs,
102 	FT_ScreenShaking,
103 	FT_FullAimAngle,
104 	FT_MiniMap,
105 	FT_SuicideDecreasesScore,
106 	FT_TeamkillDecreasesScore,
107 	FT_DeathDecreasesScore,
108 	FT_CountTeamkills,
109 	FT_AllowNegativeScore,
110 	FT_TeamInjure,
111 	FT_TeamHit,
112 	FT_SelfInjure,
113 	FT_SelfHit,
114 	FT_AllowEmptyGames,
115 	FT_HS_HideTime,		// Hide and Seek gamemode settings
116 	FT_HS_AlertTime,
117 	FT_HS_HiderVisionRange,
118 	FT_HS_HiderVisionRangeThroughWalls,
119 	FT_HS_SeekerVisionRange,
120 	FT_HS_SeekerVisionRangeThroughWalls,
121 	FT_HS_SeekerVisionAngle,
122 	FT_NewNetEngine,
123 	FT_FillWithBotsTo,
124 	FT_WormSpeedFactor,
125 	FT_WormDamageFactor,
126 	FT_WormShieldFactor,
127 	FT_InstantAirJump,
128 	FT_RelativeAirJump,
129 	FT_RelativeAirJumpDelay,
130 	FT_AllowWeaponsChange,
131 	FT_ImmediateStart,
132 	FT_DisableWpnsWhenEmpty,
133 	FT_WeaponCombos,
134 	FT_InfiniteMap,
135 	FT_MirroredMap,
136 	FT_MirroredMapSide,
137 	FT_MirroredMapTop,
138 	FT_WormFriction,
139 	FT_WormGroundFriction,
140 	FT_ProjFriction,
141 	FT_TeamScoreLimit,
142 	FT_SizeFactor,
143 	FT_CTF_AllowRopeForCarrier,
144 	FT_CTF_SpeedFactorForCarrier,
145 	FT_Race_Rounds,
146 	FT_Race_AllowWeapons,
147 	FT_Race_CheckPointRadius,
148 	FT_IndestructibleBonuses,
149 
150  	__FTI_BOTTOM
151 };
152 
153 class FeatureCompatibleSettingList {
154 public:
155 	struct Feature {
156 		std::string name;
157 		std::string humanName;
158 		ScriptVar_t var;
159 		enum Type { FCSL_SUPPORTED, FCSL_JUSTUNKNOWN, FCSL_INCOMPATIBLE };
160 		Type type;
161 	};
162 	std::map< std::string, Feature > list;
iterator()163 	Iterator< Feature & >::Ref iterator() { return GetIterator(list); }
set(const Feature & f)164 	void set(const Feature& f) { list[ f.name ] = f; }
set(const std::string & name,const std::string & humanName,const ScriptVar_t & var,Feature::Type type)165 	void set(const std::string& name, const std::string& humanName, const ScriptVar_t& var, Feature::Type type) {
166 		Feature f;
167 		f.name = name;
168 		f.humanName = humanName;
169 		f.var = var;
170 		f.type = type;
171 		set(f);
172 	}
find(const std::string & name)173 	const Feature * find( const std::string & name )
174 	{
175 		if( list.find( name ) == list.end() )
176 			return NULL;
177 		return &(list.find( name )->second);
178 	}
clear()179 	void clear() { list.clear(); }
180 };
181 
182 class FeatureSettings {
183 private:
184 	ScriptVar_t* settings;
185 public:
186 	FeatureSettings(); ~FeatureSettings();
FeatureSettings(const FeatureSettings & r)187 	FeatureSettings(const FeatureSettings& r) : settings(NULL) { (*this) = r; }
188 	FeatureSettings& operator=(const FeatureSettings& r);
189 
190 	ScriptVar_t& operator[](FeatureIndex i) { return settings[i]; }
191 	ScriptVar_t& operator[](Feature* f) { return settings[f - &featureArray[0]]; }
192 	const ScriptVar_t& operator[](FeatureIndex i) const { return settings[i]; }
193 	const ScriptVar_t& operator[](Feature* f) const { return settings[f - &featureArray[0]]; }
194 
195 	ScriptVar_t hostGet(FeatureIndex i);
hostGet(Feature * f)196 	ScriptVar_t hostGet(Feature* f) { return hostGet(FeatureIndex(f - &featureArray[0])); }
197 	bool olderClientsSupportSetting(Feature* f);
198 };
199 
200 #endif
201