36 } |
37 } |
37 } |
38 } |
38 return result; |
39 return result; |
39 } |
40 } |
40 |
41 |
41 int flib_ipc_append_mapconf(flib_vector *vec, flib_map *map, bool mappreview) { |
42 int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) { |
42 int result = -1; |
43 int result = -1; |
43 flib_vector *tempvector = flib_vector_create(); |
44 flib_vector *tempvector = flib_vector_create(); |
44 if(!vec || !map) { |
45 if(!vec || !map) { |
45 flib_log_e("null parameter in flib_ipc_append_mapconf"); |
46 flib_log_e("null parameter in flib_ipc_append_mapconf"); |
46 } else if(tempvector) { |
47 } else if(tempvector) { |
94 } else { |
95 } else { |
95 return flib_ipc_append_message(vec, "eseed %s", seed); |
96 return flib_ipc_append_message(vec, "eseed %s", seed); |
96 } |
97 } |
97 } |
98 } |
98 |
99 |
99 int flib_ipc_append_gamescheme(flib_vector *vec, flib_cfg *scheme, flib_cfg_meta *meta) { |
100 int flib_ipc_append_gamescheme(flib_vector *vec, const flib_cfg *scheme) { |
100 int result = -1; |
101 int result = -1; |
101 flib_vector *tempvector = flib_vector_create(); |
102 flib_vector *tempvector = flib_vector_create(); |
102 if(!vec || !scheme || !meta) { |
103 if(!vec || !scheme) { |
103 flib_log_e("null parameter in flib_ipc_append_gamescheme"); |
104 flib_log_e("null parameter in flib_ipc_append_gamescheme"); |
104 } else if(tempvector) { |
105 } else if(tempvector) { |
|
106 const flib_cfg_meta *meta = scheme->meta; |
105 bool error = false; |
107 bool error = false; |
106 uint32_t gamemods = 0; |
108 uint32_t gamemods = 0; |
107 for(int i=0; i<meta->modCount; i++) { |
109 for(int i=0; i<meta->modCount; i++) { |
108 if(scheme->mods[i]) { |
110 if(scheme->mods[i]) { |
109 gamemods |= (1<<meta->mods[i].bitmaskIndex); |
111 gamemods |= (1<<meta->mods[i].bitmaskIndex); |
110 } |
112 } |
111 } |
113 } |
112 error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, gamemods); |
114 error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, gamemods); |
113 for(int i=0; i<meta->settingCount; i++) { |
115 for(int i=0; i<meta->settingCount; i++) { |
114 int value = scheme->settings[i]; |
116 int value = scheme->settings[i]; |
115 if(meta->settings[i].checkOverMax) { |
117 if(meta->settings[i].maxMeansInfinity) { |
116 value = value>meta->settings[i].max ? meta->settings[i].max : value; |
118 value = value>=meta->settings[i].max ? 9999 : value; |
117 } |
119 } |
118 if(meta->settings[i].times1000) { |
120 if(meta->settings[i].times1000) { |
119 value *= 1000; |
121 value *= 1000; |
120 } |
122 } |
121 error |= flib_ipc_append_message(tempvector, "%s %i", meta->settings[i].engineCommand, value); |
123 error |= flib_ipc_append_message(tempvector, "%s %i", meta->settings[i].engineCommand, value); |
131 } |
133 } |
132 flib_vector_destroy(tempvector); |
134 flib_vector_destroy(tempvector); |
133 return result; |
135 return result; |
134 } |
136 } |
135 |
137 |
136 // FIXME shared ammo will break per-team ammo |
138 static int appendWeaponSet(flib_vector *vec, flib_weaponset *set) { |
137 int flib_ipc_append_addteam(flib_vector *vec, flib_team *team, bool perHogAmmo, bool sharedAmmo) { |
139 return flib_ipc_append_message(vec, "eammloadt %s", set->loadout) |
138 int result = -1; |
140 || flib_ipc_append_message(vec, "eammprob %s", set->crateprob) |
139 flib_vector *tempvector = flib_vector_create(); |
141 || flib_ipc_append_message(vec, "eammdelay %s", set->delay) |
140 if(!vec || !team || !team->weaponset) { |
142 || flib_ipc_append_message(vec, "eammreinf %s", set->crateammo); |
|
143 } |
|
144 |
|
145 int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) { |
|
146 int result = -1; |
|
147 flib_vector *tempvector = flib_vector_create(); |
|
148 if(!vec || !team) { |
141 flib_log_e("invalid parameter in flib_ipc_append_addteam"); |
149 flib_log_e("invalid parameter in flib_ipc_append_addteam"); |
142 } else if(tempvector) { |
150 } else if(tempvector) { |
143 bool error = false; |
151 bool error = false; |
144 error |= flib_ipc_append_message(tempvector, "eammloadt %s", team->weaponset->loadout); |
152 |
145 error |= flib_ipc_append_message(tempvector, "eammprob %s", team->weaponset->crateprob); |
153 if(!perHogAmmo && !noAmmoStore) { |
146 error |= flib_ipc_append_message(tempvector, "eammdelay %s", team->weaponset->delay); |
154 error |= appendWeaponSet(tempvector, team->hogs[0].weaponset); |
147 error |= flib_ipc_append_message(tempvector, "eammreinf %s", team->weaponset->crateammo); |
|
148 if(!perHogAmmo) { |
|
149 error |= flib_ipc_append_message(tempvector, "eammstore"); |
155 error |= flib_ipc_append_message(tempvector, "eammstore"); |
150 } |
156 } |
151 |
157 |
152 char *hash = team->hash ? team->hash : "00000000000000000000000000000000"; |
158 char *hash = team->hash ? team->hash : "00000000000000000000000000000000"; |
153 error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", hash, team->color, team->name); |
159 error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", hash, team->color, team->name); |
164 for(int i=0; i<team->bindingCount; i++) { |
170 for(int i=0; i<team->bindingCount; i++) { |
165 error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action); |
171 error |= flib_ipc_append_message(tempvector, "ebind %s %s", team->bindings[i].binding, team->bindings[i].action); |
166 } |
172 } |
167 |
173 |
168 for(int i=0; i<team->hogsInGame; i++) { |
174 for(int i=0; i<team->hogsInGame; i++) { |
|
175 if(perHogAmmo && !noAmmoStore) { |
|
176 error |= appendWeaponSet(tempvector, team->hogs[i].weaponset); |
|
177 } |
169 error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name); |
178 error |= flib_ipc_append_message(tempvector, "eaddhh %i %i %s", team->hogs[i].difficulty, team->hogs[i].initialHealth, team->hogs[i].name); |
170 error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat); |
179 error |= flib_ipc_append_message(tempvector, "ehat %s", team->hogs[i].hat); |
171 } |
180 } |
172 |
181 |
173 if(!error) { |
182 if(!error) { |
179 } |
188 } |
180 } |
189 } |
181 flib_vector_destroy(tempvector); |
190 flib_vector_destroy(tempvector); |
182 return result; |
191 return result; |
183 } |
192 } |
|
193 |
|
194 static bool getGameMod(const flib_cfg *conf, int maskbit) { |
|
195 for(int i=0; i<conf->meta->modCount; i++) { |
|
196 if(conf->meta->mods[i].bitmaskIndex == maskbit) { |
|
197 return conf->mods[i]; |
|
198 } |
|
199 } |
|
200 flib_log_e("Unable to find game mod with mask bit %i", maskbit); |
|
201 return false; |
|
202 } |
|
203 |
|
204 int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) { |
|
205 int result = -1; |
|
206 flib_vector *tempvector = flib_vector_create(); |
|
207 if(!vec || !setup) { |
|
208 flib_log_e("null parameter in flib_ipc_append_fullconfig"); |
|
209 } else if(tempvector) { |
|
210 bool error = false; |
|
211 bool perHogAmmo = false; |
|
212 bool sharedAmmo = false; |
|
213 |
|
214 error |= flib_ipc_append_message(vec, netgame ? "TN" : "TL"); |
|
215 error |= flib_ipc_append_seed(vec, setup->seed); |
|
216 if(setup->map) { |
|
217 error |= flib_ipc_append_mapconf(tempvector, setup->map, false); |
|
218 } |
|
219 if(setup->script) { |
|
220 error |= flib_ipc_append_message(tempvector, "escript %s", setup->script); |
|
221 } |
|
222 if(setup->gamescheme) { |
|
223 error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme); |
|
224 sharedAmmo = getGameMod(setup->gamescheme, GAMEMOD_SHAREDAMMO_MASKBIT); |
|
225 // Shared ammo has priority over per-hog ammo |
|
226 perHogAmmo = !sharedAmmo && getGameMod(setup->gamescheme, GAMEMOD_PERHOGAMMO_MASKBIT); |
|
227 } |
|
228 if(setup->teams && setup->teamcount>0) { |
|
229 uint32_t *clanColors = flib_calloc(setup->teamcount, sizeof(uint32_t)); |
|
230 if(!clanColors) { |
|
231 error = true; |
|
232 } else { |
|
233 int clanCount = 0; |
|
234 for(int i=0; i<setup->teamcount; i++) { |
|
235 flib_team *team = setup->teams[i]; |
|
236 bool newClan = false; |
|
237 |
|
238 // Find the clan index of this team (clans are identified by color). |
|
239 // The upper 8 bits (alpha) are ignored in the engine as well. |
|
240 uint32_t color = team->color&UINT32_C(0x00ffffff); |
|
241 int clan = 0; |
|
242 while(clan<clanCount && clanColors[clan] != color) { |
|
243 clan++; |
|
244 } |
|
245 if(clan==clanCount) { |
|
246 newClan = true; |
|
247 clanCount++; |
|
248 clanColors[clan] = color; |
|
249 } |
|
250 |
|
251 // If shared ammo is active, only add an ammo store for the first team in each clan. |
|
252 bool noAmmoStore = sharedAmmo&&!newClan; |
|
253 error |= flib_ipc_append_addteam(tempvector, setup->teams[i], perHogAmmo, noAmmoStore); |
|
254 } |
|
255 } |
|
256 free(clanColors); |
|
257 } |
|
258 error |= flib_ipc_append_message(tempvector, "!"); |
|
259 |
|
260 if(!error) { |
|
261 // Message created, now we can copy everything. |
|
262 flib_constbuffer constbuf = flib_vector_as_constbuffer(tempvector); |
|
263 if(flib_vector_append(vec, constbuf.data, constbuf.size) == constbuf.size) { |
|
264 result = 0; |
|
265 } |
|
266 } |
|
267 } |
|
268 return result; |
|
269 } |