project_files/frontlib/model/team.c
branchhedgeroid
changeset 7857 2bc61f8841a1
parent 7497 7e1d72fc03c7
child 10017 de822cd3df3a
equal deleted inserted replaced
7855:ddcdedd3330b 7857:2bc61f8841a1
       
     1 /*
       
     2  * Hedgewars, a free turn based strategy game
       
     3  * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU General Public License
       
     7  * as published by the Free Software Foundation; either version 2
       
     8  * of the License, or (at your option) any later version.
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program; if not, write to the Free Software
       
    17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
       
    18  */
       
    19 
       
    20 #include "team.h"
       
    21 
       
    22 #include "../util/inihelper.h"
       
    23 #include "../util/util.h"
       
    24 #include "../util/logging.h"
       
    25 
       
    26 #include <string.h>
       
    27 #include <stdlib.h>
       
    28 
       
    29 static flib_team *from_ini_handleError(flib_team *result, flib_ini *settingfile) {
       
    30 	flib_ini_destroy(settingfile);
       
    31 	flib_team_destroy(result);
       
    32 	return NULL;
       
    33 }
       
    34 
       
    35 flib_team *flib_team_from_ini(const char *filename) {
       
    36 	if(log_badargs_if(filename==NULL)) {
       
    37 		return NULL;
       
    38 	}
       
    39 
       
    40 	flib_team *result = flib_calloc(1, sizeof(flib_team));
       
    41 	flib_ini *ini = NULL;
       
    42 
       
    43 	if(!result) {
       
    44 		return from_ini_handleError(result, ini);
       
    45 	}
       
    46 
       
    47 	ini = flib_ini_load(filename);
       
    48 	if(!ini) {
       
    49 		flib_log_e("Error loading team file %s", filename);
       
    50 		return from_ini_handleError(result, ini);
       
    51 	}
       
    52 
       
    53 	if(flib_ini_enter_section(ini, "team")) {
       
    54 		flib_log_e("Missing section \"Team\" in team file %s", filename);
       
    55 		return from_ini_handleError(result, ini);
       
    56 	}
       
    57 	bool error = false;
       
    58 	error |= flib_ini_get_str(ini, &result->name, "name");
       
    59 	error |= flib_ini_get_str(ini, &result->grave, "grave");
       
    60 	error |= flib_ini_get_str(ini, &result->fort, "fort");
       
    61 	error |= flib_ini_get_str(ini, &result->voicepack, "voicepack");
       
    62 	error |= flib_ini_get_str(ini, &result->flag, "flag");
       
    63 	error |= flib_ini_get_int(ini, &result->rounds, "rounds");
       
    64 	error |= flib_ini_get_int(ini, &result->wins, "wins");
       
    65 	error |= flib_ini_get_int(ini, &result->campaignProgress, "campaignprogress");
       
    66 
       
    67 	int difficulty = 0;
       
    68 	error |= flib_ini_get_int(ini, &difficulty, "difficulty");
       
    69 
       
    70 	if(error) {
       
    71 		flib_log_e("Missing or malformed entry in section \"Team\" in file %s", filename);
       
    72 		return from_ini_handleError(result, ini);
       
    73 	}
       
    74 
       
    75 	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
    76 		char sectionName[32];
       
    77 		if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) {
       
    78 			return from_ini_handleError(result, ini);
       
    79 		}
       
    80 		if(flib_ini_enter_section(ini, sectionName)) {
       
    81 			flib_log_e("Missing section \"%s\" in team file %s", sectionName, filename);
       
    82 			return from_ini_handleError(result, ini);
       
    83 		}
       
    84 		flib_hog *hog = &result->hogs[i];
       
    85 		error |= flib_ini_get_str(ini, &hog->name, "name");
       
    86 		error |= flib_ini_get_str(ini, &hog->hat, "hat");
       
    87 		error |= flib_ini_get_int(ini, &hog->rounds, "rounds");
       
    88 		error |= flib_ini_get_int(ini, &hog->kills, "kills");
       
    89 		error |= flib_ini_get_int(ini, &hog->deaths, "deaths");
       
    90 		error |= flib_ini_get_int(ini, &hog->suicides, "suicides");
       
    91 		result->hogs[i].difficulty = difficulty;
       
    92 		result->hogs[i].initialHealth = TEAM_DEFAULT_HEALTH;
       
    93 
       
    94 		if(error) {
       
    95 			flib_log_e("Missing or malformed entry in section \"%s\" in file %s", sectionName, filename);
       
    96 			return from_ini_handleError(result, ini);
       
    97 		}
       
    98 	}
       
    99 
       
   100 	if(!flib_ini_enter_section(ini, "binds")) {
       
   101 		result->bindingCount = flib_ini_get_keycount(ini);
       
   102 		if(result->bindingCount<0) {
       
   103 			flib_log_e("Error reading bindings from file %s", filename);
       
   104 			result->bindingCount = 0;
       
   105 		}
       
   106 		result->bindings = flib_calloc(result->bindingCount, sizeof(flib_binding));
       
   107 		if(!result->bindings) {
       
   108 			return from_ini_handleError(result, ini);
       
   109 		}
       
   110 		for(int i=0; i<result->bindingCount; i++) {
       
   111 			char *keyname = flib_ini_get_keyname(ini, i);
       
   112 			if(!keyname) {
       
   113 				error = true;
       
   114 			} else {
       
   115 				result->bindings[i].action = flib_urldecode(keyname);
       
   116 				error |= !result->bindings[i].action;
       
   117 				error |= flib_ini_get_str(ini, &result->bindings[i].binding, keyname);
       
   118 			}
       
   119 			free(keyname);
       
   120 		}
       
   121 	}
       
   122 
       
   123 	if(error) {
       
   124 		flib_log_e("Error reading team file %s", filename);
       
   125 		return from_ini_handleError(result, ini);
       
   126 	}
       
   127 
       
   128 	flib_ini_destroy(ini);
       
   129 	return result;
       
   130 }
       
   131 
       
   132 void flib_team_destroy(flib_team *team) {
       
   133 	if(team) {
       
   134 		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
   135 			free(team->hogs[i].name);
       
   136 			free(team->hogs[i].hat);
       
   137 			flib_weaponset_destroy(team->hogs[i].weaponset);
       
   138 		}
       
   139 		free(team->name);
       
   140 		free(team->grave);
       
   141 		free(team->fort);
       
   142 		free(team->voicepack);
       
   143 		free(team->flag);
       
   144 		if(team->bindings) {
       
   145 			for(int i=0; i<team->bindingCount; i++) {
       
   146 				free(team->bindings[i].action);
       
   147 				free(team->bindings[i].binding);
       
   148 			}
       
   149 		}
       
   150 		free(team->bindings);
       
   151 		free(team->ownerName);
       
   152 		free(team);
       
   153 	}
       
   154 }
       
   155 
       
   156 static int writeTeamSection(const flib_team *team, flib_ini *ini) {
       
   157 	if(flib_ini_create_section(ini, "team")) {
       
   158 		return -1;
       
   159 	}
       
   160 	bool error = false;
       
   161 	error |= flib_ini_set_str(ini, "name",  team->name);
       
   162 	error |= flib_ini_set_str(ini, "grave", team->grave);
       
   163 	error |= flib_ini_set_str(ini, "fort", team->fort);
       
   164 	error |= flib_ini_set_str(ini, "voicepack", team->voicepack);
       
   165 	error |= flib_ini_set_str(ini, "flag", team->flag);
       
   166 	error |= flib_ini_set_int(ini, "rounds", team->rounds);
       
   167 	error |= flib_ini_set_int(ini, "wins", team->wins);
       
   168 	error |= flib_ini_set_int(ini, "campaignprogress", team->campaignProgress);
       
   169 	error |= flib_ini_set_int(ini, "difficulty", team->hogs[0].difficulty);
       
   170 	return error;
       
   171 }
       
   172 
       
   173 static int writeHogSections(const flib_team *team, flib_ini *ini) {
       
   174 	for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
   175 		const flib_hog *hog = &team->hogs[i];
       
   176 		char sectionName[32];
       
   177 		if(snprintf(sectionName, sizeof(sectionName), "hedgehog%i", i) <= 0) {
       
   178 			return -1;
       
   179 		}
       
   180 		if(flib_ini_create_section(ini, sectionName)) {
       
   181 			return -1;
       
   182 		}
       
   183 		bool error = false;
       
   184 		error |= flib_ini_set_str(ini, "name", hog->name);
       
   185 		error |= flib_ini_set_str(ini, "hat", hog->hat);
       
   186 		error |= flib_ini_set_int(ini, "rounds", hog->rounds);
       
   187 		error |= flib_ini_set_int(ini, "kills", hog->kills);
       
   188 		error |= flib_ini_set_int(ini, "deaths", hog->deaths);
       
   189 		error |= flib_ini_set_int(ini, "suicides", hog->suicides);
       
   190 		if(error) {
       
   191 			return error;
       
   192 		}
       
   193 	}
       
   194 	return 0;
       
   195 }
       
   196 
       
   197 static int writeBindingSection(const flib_team *team, flib_ini *ini) {
       
   198 	if(team->bindingCount == 0) {
       
   199 		return 0;
       
   200 	}
       
   201 	if(flib_ini_create_section(ini, "binds")) {
       
   202 		return -1;
       
   203 	}
       
   204 	for(int i=0; i<team->bindingCount; i++) {
       
   205 		bool error = false;
       
   206 		char *action = flib_urlencode(team->bindings[i].action);
       
   207 		if(action) {
       
   208 			error |= flib_ini_set_str(ini, action, team->bindings[i].binding);
       
   209 			free(action);
       
   210 		} else {
       
   211 			error = true;
       
   212 		}
       
   213 		if(error) {
       
   214 			return error;
       
   215 		}
       
   216 	}
       
   217 	return 0;
       
   218 }
       
   219 
       
   220 int flib_team_to_ini(const char *filename, const flib_team *team) {
       
   221 	int result = -1;
       
   222 	if(!log_badargs_if2(filename==NULL, team==NULL)) {
       
   223 		flib_ini *ini = flib_ini_create(filename);
       
   224 		bool error = false;
       
   225 		error |= writeTeamSection(team, ini);
       
   226 		error |= writeHogSections(team, ini);
       
   227 		error |= writeBindingSection(team, ini);
       
   228 		if(!error) {
       
   229 			result = flib_ini_save(ini, filename);
       
   230 		}
       
   231 		flib_ini_destroy(ini);
       
   232 	}
       
   233 	return result;
       
   234 }
       
   235 
       
   236 int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set) {
       
   237 	if(team) {
       
   238 		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
   239 			flib_weaponset_destroy(team->hogs[i].weaponset);
       
   240 			team->hogs[i].weaponset = flib_weaponset_copy(set);
       
   241 			if(set && !team->hogs[i].weaponset) {
       
   242 				return -1;
       
   243 			}
       
   244 		}
       
   245 	}
       
   246 	return 0;
       
   247 }
       
   248 
       
   249 void flib_team_set_health(flib_team *team, int health) {
       
   250 	if(team) {
       
   251 		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
   252 			team->hogs[i].initialHealth = health;
       
   253 		}
       
   254 	}
       
   255 }
       
   256 
       
   257 static char *strdupWithError(const char *in, bool *error) {
       
   258 	char *out = flib_strdupnull(in);
       
   259 	if(in && !out) {
       
   260 		*error = true;
       
   261 	}
       
   262 	return out;
       
   263 }
       
   264 
       
   265 flib_team *flib_team_copy(const flib_team *team) {
       
   266 	flib_team *result = NULL;
       
   267 	if(team) {
       
   268 		flib_team *tmpTeam = flib_calloc(1, sizeof(flib_team));
       
   269 		if(tmpTeam) {
       
   270 			bool error = false;
       
   271 
       
   272 			for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
       
   273 				tmpTeam->hogs[i].name = strdupWithError(team->hogs[i].name, &error);
       
   274 				tmpTeam->hogs[i].hat = strdupWithError(team->hogs[i].hat, &error);
       
   275 				tmpTeam->hogs[i].rounds = team->hogs[i].rounds;
       
   276 				tmpTeam->hogs[i].kills = team->hogs[i].kills;
       
   277 				tmpTeam->hogs[i].deaths = team->hogs[i].deaths;
       
   278 				tmpTeam->hogs[i].suicides = team->hogs[i].suicides;
       
   279 				tmpTeam->hogs[i].difficulty = team->hogs[i].difficulty;
       
   280 				tmpTeam->hogs[i].initialHealth = team->hogs[i].initialHealth;
       
   281 				tmpTeam->hogs[i].weaponset = flib_weaponset_copy(team->hogs[i].weaponset);
       
   282 				if(team->hogs[i].weaponset && !tmpTeam->hogs[i].weaponset) {
       
   283 					error = true;
       
   284 				}
       
   285 			}
       
   286 
       
   287 			tmpTeam->name = strdupWithError(team->name, &error);
       
   288 			tmpTeam->grave = strdupWithError(team->grave, &error);
       
   289 			tmpTeam->fort = strdupWithError(team->fort, &error);
       
   290 			tmpTeam->voicepack = strdupWithError(team->voicepack, &error);
       
   291 			tmpTeam->flag = strdupWithError(team->flag, &error);
       
   292 			tmpTeam->ownerName = strdupWithError(team->ownerName, &error);
       
   293 
       
   294 			tmpTeam->bindingCount = team->bindingCount;
       
   295 			if(team->bindings) {
       
   296 				tmpTeam->bindings = flib_calloc(team->bindingCount, sizeof(flib_binding));
       
   297 				if(tmpTeam->bindings) {
       
   298 					for(int i=0; i<tmpTeam->bindingCount; i++) {
       
   299 						tmpTeam->bindings[i].action = strdupWithError(team->bindings[i].action, &error);
       
   300 						tmpTeam->bindings[i].binding = strdupWithError(team->bindings[i].binding, &error);
       
   301 					}
       
   302 				} else {
       
   303 					error = true;
       
   304 				}
       
   305 			}
       
   306 
       
   307 			tmpTeam->rounds = team->rounds;
       
   308 			tmpTeam->wins = team->wins;
       
   309 			tmpTeam->campaignProgress = team->campaignProgress;
       
   310 
       
   311 			tmpTeam->colorIndex = team->colorIndex;
       
   312 			tmpTeam->hogsInGame = team->hogsInGame;
       
   313 			tmpTeam->remoteDriven = team->remoteDriven;
       
   314 
       
   315 			if(!error) {
       
   316 				result = tmpTeam;
       
   317 				tmpTeam = 0;
       
   318 			}
       
   319 		}
       
   320 		flib_team_destroy(tmpTeam);
       
   321 	}
       
   322 	return result;
       
   323 }