Пример #1
0
/**
 * @brief Load callback for savegames in XML Format
 * @param[in] parent XML Node structure, where we get the information from
 */
bool INT_LoadXML (xmlNode_t *parent)
{
	xmlNode_t *node;
	xmlNode_t *interestsNode = XML_GetNode(parent, SAVE_INTERESTS);
	bool success = true;

	ccs.lastInterestIncreaseDelay = XML_GetInt(interestsNode, SAVE_INTERESTS_LASTINCREASEDELAY, 0);
	ccs.lastMissionSpawnedDelay = XML_GetInt(interestsNode, SAVE_INTERESTS_LASTMISSIONSPAWNEDDELAY, 0);
	ccs.overallInterest = XML_GetInt(interestsNode, SAVE_INTERESTS_OVERALL, 0);
	Com_RegisterConstList(saveInterestConstants);
	for (node = XML_GetNode(interestsNode, SAVE_INTERESTS_INTEREST); node;
			node = XML_GetNextNode(node, interestsNode, SAVE_INTERESTS_INTEREST)) {
		const char *categoryId = XML_GetString(node, SAVE_INTERESTS_ID);
		int cat;

		if (!Com_GetConstInt(categoryId, (int*) &cat)) {
			Com_Printf("Invalid interest category '%s'\n", categoryId);
			success = false;
			break;
		}
		ccs.interest[cat]= XML_GetInt(node, SAVE_INTERESTS_VAL, 0);
	}
	Com_UnregisterConstList(saveInterestConstants);
	return success;
}
Пример #2
0
/**
 * @brief Load callback for savegames in XML Format
 * @param[in] parent XML Node structure, where we get the information from
 */
qboolean AIRFIGHT_LoadXML (xmlNode_t *parent)
{
	int i;
	xmlNode_t *node;

	for (i = 0, node = XML_GetNode(parent, SAVE_AIRFIGHT_PROJECTILE); i < MAX_PROJECTILESONGEOSCAPE && node;
			node = XML_GetNextNode(node, parent, SAVE_AIRFIGHT_PROJECTILE), i++) {
		technology_t *tech = RS_GetTechByProvided(XML_GetString(node, SAVE_AIRFIGHT_ITEMID));
		int j;
		xmlNode_t *positions;
		xmlNode_t *attackingAircraft;
		xmlNode_t *aimedAircraft;
		aircraftProjectile_t *projectile = &ccs.projectiles[i];

		if (!tech) {
			Com_Printf("AIR_Load: Could not get technology of projectile %i\n", i);
			return qfalse;
		}

		projectile->aircraftItem = INVSH_GetItemByID(tech->provides);

		for (j = 0, positions = XML_GetPos2(node, SAVE_AIRFIGHT_POS, projectile->pos[0]); j < MAX_MULTIPLE_PROJECTILES && positions;
		     j++, positions = XML_GetNextPos2(positions, node, SAVE_AIRFIGHT_POS, projectile->pos[j]))
			;
		projectile->numProjectiles = j;
		XML_GetPos3(node, SAVE_AIRFIGHT_IDLETARGET, projectile->idleTarget);

		projectile->time = XML_GetInt(node, SAVE_AIRFIGHT_TIME, 0);
		projectile->angle = XML_GetFloat(node, SAVE_AIRFIGHT_ANGLE, 0.0);
		projectile->bullets = XML_GetBool(node, SAVE_AIRFIGHT_BULLET, qfalse);
		projectile->beam = XML_GetBool(node, SAVE_AIRFIGHT_BEAM, qfalse);

		if ((attackingAircraft = XML_GetNode(node, SAVE_AIRFIGHT_ATTACKINGAIRCRAFT))) {
			if (XML_GetBool(attackingAircraft, SAVE_AIRFIGHT_ISUFO, qfalse))
				/** @todo 0 as default might be incorrect */
				projectile->attackingAircraft = UFO_GetByIDX(XML_GetInt(attackingAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, 0));
			else
				projectile->attackingAircraft = AIR_AircraftGetFromIDX(XML_GetInt(attackingAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, AIRCRAFT_INVALID));
		} else {
			projectile->attackingAircraft = NULL;
		}
		if ((aimedAircraft = XML_GetNode(node, SAVE_AIRFIGHT_AIMEDAIRCRAFT))) {
			if (XML_GetBool(aimedAircraft, SAVE_AIRFIGHT_ISUFO, qfalse))
				/** @todo 0 as default might be incorrect */
				projectile->aimedAircraft = UFO_GetByIDX(XML_GetInt(aimedAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, 0));
			else
				projectile->aimedAircraft = AIR_AircraftGetFromIDX(XML_GetInt(aimedAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, AIRCRAFT_INVALID));
		} else {
			projectile->aimedAircraft = NULL;
		}
	}
	ccs.numProjectiles = i;

	return qtrue;
}
Пример #3
0
/**
 * @brief Load callback for savegames in XML Format
 * @param[in] parent XML Node structure, where we get the information from
 */
qboolean STATS_LoadXML (xmlNode_t *parent)
{
	xmlNode_t * stats;
	qboolean success = qtrue;

	stats = XML_GetNode(parent, SAVE_STATS_STATS);
	if (!stats) {
		Com_Printf("Did not find stats entry in xml!\n");
		return qfalse;
	}
	ccs.campaignStats.missions = XML_GetInt(stats, SAVE_STATS_MISSIONS, 0);
	ccs.campaignStats.missionsWon = XML_GetInt(stats, SAVE_STATS_MISSIONSWON, 0);
	ccs.campaignStats.missionsLost = XML_GetInt(stats, SAVE_STATS_MISSIONSLOST, 0);
	ccs.campaignStats.basesBuilt = XML_GetInt(stats, SAVE_STATS_BASESBUILT, 0);
	ccs.campaignStats.basesAttacked = XML_GetInt(stats, SAVE_STATS_BASESATTACKED, 0);
	ccs.campaignStats.installationsBuilt = XML_GetInt(stats, SAVE_STATS_INSTALLATIONSBUILT, 0);
	ccs.campaignStats.interceptions = XML_GetInt(stats, SAVE_STATS_INTERCEPTIONS, 0);
	ccs.campaignStats.soldiersLost = XML_GetInt(stats, SAVE_STATS_SOLDIERSLOST, 0);
	ccs.campaignStats.soldiersNew = XML_GetInt(stats, SAVE_STATS_SOLDIERSNEW, 0);
	ccs.campaignStats.killedAliens = XML_GetInt(stats, SAVE_STATS_KILLEDALIENS, 0);
	ccs.campaignStats.rescuedCivilians = XML_GetInt(stats, SAVE_STATS_RESCUEDCIVILIANS, 0);
	ccs.campaignStats.researchedTechnologies = XML_GetInt(stats, SAVE_STATS_RESEARCHEDTECHNOLOGIES, 0);
	ccs.campaignStats.moneyInterceptions = XML_GetInt(stats, SAVE_STATS_MONEYINTERCEPTIONS, 0);
	ccs.campaignStats.moneyBases = XML_GetInt(stats, SAVE_STATS_MONEYBASES, 0);
	ccs.campaignStats.moneyResearch = XML_GetInt(stats, SAVE_STATS_MONEYRESEARCH, 0);
	ccs.campaignStats.moneyWeapons = XML_GetInt(stats, SAVE_STATS_MONEYWEAPONS, 0);
	ccs.campaignStats.ufosDetected = XML_GetInt(stats, SAVE_STATS_UFOSDETECTED, 0);
	ccs.campaignStats.alienBasesBuilt = XML_GetInt(stats, SAVE_STATS_ALIENBASESBUILT, 0);
	ccs.campaignStats.ufosStored = XML_GetInt(stats, SAVE_STATS_UFOSSTORED, 0);
	ccs.campaignStats.aircraftHad = XML_GetInt(stats, SAVE_STATS_AIRCRAFTHAD, 0);

	/* freeing the memory below this node */
	mxmlDelete(stats);
	return success;
}
Пример #4
0
/**
 * @brief retrieve the date data from an XML Node
 * @param[in] parent XML Node structure to get child from
 * @param[in] name Name of the pos node
 * @param[out] day Day part of the date to fill
 * @param[out] sec Second part of the date to fill
 * @return pointer to the node the data was retrieved from
 * @return nullptr if no node with name found
 */
xmlNode_t* XML_GetDate (xmlNode_t* parent, const char* name, int* day, int* sec)
{
	xmlNode_t* p = XML_GetNode(parent, name);
	if (!p)
		return nullptr;
	*day = XML_GetInt(p, "day", 0);
	*sec = XML_GetInt(p, "sec", 0);
	return p;
}
Пример #5
0
/**
 * @brief retrieve the first Pos2 data from an XML Node
 * @param[in] parent XML Node structure to get child from
 * @param[in] name Name of the pos node
 * @param[out] pos vec2_t structure to fill
 * @return pointer to the node the data was retrieved from
 * @return nullptr if no node with name found
 */
xmlNode_t* XML_GetPos2 (xmlNode_t* parent, const char* name, vec2_t pos)
{
	xmlNode_t* p = XML_GetNode(parent, name);
	if (!p)
		return nullptr;
	pos[0] = XML_GetFloat(p, "x", 0);
	pos[1] = XML_GetFloat(p, "y", 0);
	return p;
}
Пример #6
0
/**
 * @brief Loads the given savegame from an xml File.
 * @return true on load success false on failures
 * @param[in] file The Filename to load from (without extension)
 * @param[out] error On failure an errormessage may be set.
 */
bool SAV_GameLoad (const char *file, const char **error)
{
	char filename[MAX_OSPATH];
	qFILE f;
	int i, clen;
	xmlNode_t *topNode, *node;
	saveFileHeader_t header;

	Q_strncpyz(filename, file, sizeof(filename));

	/* open file */
	FS_OpenFile(va("save/%s.%s", filename, SAVEGAME_EXTENSION), &f, FILE_READ);
	if (!f.f) {
		Com_Printf("Couldn't open file '%s'\n", filename);
		*error = "File not found";
		return false;
	}

	clen = FS_FileLength(&f);
	byte* const cbuf = Mem_PoolAllocTypeN(byte, clen + 1 /* for '\0' if not compressed */, cp_campaignPool);
	if (FS_Read(cbuf, clen, &f) != clen)
		Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
	FS_CloseFile(&f);
	Com_Printf("Loading savegame xml (size %d)\n", clen);

	memcpy(&header, cbuf, sizeof(header));
	/* swap all int values if needed */
	header.compressed = LittleLong(header.compressed);
	header.version = LittleLong(header.version);
	header.xmlSize = LittleLong(header.xmlSize);
	/* doing some header verification */
	if (!SAV_VerifyHeader(&header)) {
		/* our header is not valid, we MUST abort loading the game! */
		Com_Printf("The Header of the savegame '%s.%s' is corrupted. Loading aborted\n", filename, SAVEGAME_EXTENSION);
		Mem_Free(cbuf);
		*error = "Corrupted header";
		return false;
	}

	Com_Printf("Loading savegame\n"
			"...version: %i\n"
			"...game version: %s\n"
			"...xml Size: %i, compressed? %c\n",
			header.version, header.gameVersion, header.xmlSize, header.compressed ? 'y' : 'n');

	if (header.compressed) {
		uLongf      len = header.xmlSize + 1 /* for '\0' */;
		byte* const buf = Mem_PoolAllocTypeN(byte, len /* sic, old savegames contain one (garbage) byte more than the header says. */, cp_campaignPool);
		/* uncompress data, skipping comment header */
		const int res = uncompress(buf, &len, cbuf + sizeof(header), clen - sizeof(header));
		buf[header.xmlSize] = '\0'; /* Ensure '\0' termination. */
		Mem_Free(cbuf);

		if (res != Z_OK) {
			Mem_Free(buf);
			*error = _("Error decompressing data");
			Com_Printf("Error decompressing data in '%s'.\n", filename);
			return false;
		}
		topNode = XML_Parse((const char*)buf);
		if (!topNode) {
			Mem_Free(buf);
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return false;
		}
		Mem_Free(buf);
	} else {
		topNode = XML_Parse((const char*)(cbuf + sizeof(header)));
		Mem_Free(cbuf);
		if (!topNode) {
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return false;
		}
	}

	/* doing a subsystem run */
	GAME_ReloadMode();
	node = XML_GetNode(topNode, SAVE_ROOTNODE);
	if (!node) {
		Com_Printf("Error: Failure in loading the xml data! (savegame node not found)\n");
		mxmlDelete(topNode);
		*error = "Invalid xml data";
		return false;
	}

	Com_Printf("Load '%s' %d subsystems\n", filename, saveSubsystemsAmount);
	for (i = 0; i < saveSubsystemsAmount; i++) {
		Com_Printf("...Running subsystem '%s'\n", saveSubsystems[i].name);
		if (!saveSubsystems[i].load(node)) {
			Com_Printf("...subsystem '%s' returned false - savegame could not be loaded\n",
					saveSubsystems[i].name);
			*error = va("Could not load subsystem %s", saveSubsystems[i].name);
			return false;
		} else
			Com_Printf("...subsystem '%s' - loaded.\n", saveSubsystems[i].name);
	}
	mxmlDelete(node);
	mxmlDelete(topNode);

	if (!SAV_GameActionsAfterLoad()) {
		Com_Printf("Savegame postprocessing returned false - savegame could not be loaded\n");
		*error = "Postprocessing failed";
		return false;
	}

	Com_Printf("File '%s' successfully loaded from %s xml savegame.\n",
			filename, header.compressed ? "compressed" : "");

	cgi->UI_InitStack("geoscape", NULL, true, true);
	return true;
}
Пример #7
0
/**
 * @brief Load callback for savegames
 * @param[in] p XML Node structure, where we get the information from
 * @sa INS_SaveXML
 * @sa SAV_GameLoadXML
 * @sa INS_LoadItemSlots
 */
qboolean INS_LoadXML (xmlNode_t *p)
{
	xmlNode_t *n = XML_GetNode(p, SAVE_INSTALLATION_INSTALLATIONS);
	xmlNode_t *s;
	int i = 0;
	qboolean success = qtrue;

	if (!n)
		return qfalse;

	Com_RegisterConstList(saveInstallationConstants);
	for (s = XML_GetNode(n, SAVE_INSTALLATION_INSTALLATION); s; s = XML_GetNextNode(s,n, SAVE_INSTALLATION_INSTALLATION), i++) {
		xmlNode_t *ss;
		installation_t inst;
		installation_t *instp;
		const char *instID = XML_GetString(s, SAVE_INSTALLATION_TEMPLATEID);
		const char *instStat = XML_GetString(s, SAVE_INSTALLATION_STATUS);

		inst.idx = XML_GetInt(s, SAVE_INSTALLATION_IDX, -1);
		if (inst.idx < 0) {
			/** @todo fallback code for compatibility */
			inst.idx = i;
		}
		inst.installationTemplate = INS_GetInstallationTemplateFromInstallationID(instID);
		if (!inst.installationTemplate) {
			Com_Printf("Could not find installation template '%s'\n", instID);
			success = qfalse;
			break;
		}

		if (!Com_GetConstIntFromNamespace(SAVE_INSTALLATIONSTATUS_NAMESPACE, instStat, (int*) &inst.installationStatus)) {
			Com_Printf("Invalid installation status '%s'\n", instStat);
			success = qfalse;
			break;
		}

		Q_strncpyz(inst.name, XML_GetString(s, SAVE_INSTALLATION_NAME), sizeof(inst.name));
		XML_GetPos3(s, SAVE_INSTALLATION_POS, inst.pos);

		inst.installationDamage = XML_GetInt(s, SAVE_INSTALLATION_DAMAGE, 0);
		inst.alienInterest = XML_GetFloat(s, SAVE_INSTALLATION_ALIENINTEREST, 0.0);
		inst.buildStart = XML_GetInt(s, SAVE_INSTALLATION_BUILDSTART, 0);

		/* Radar */
		RADAR_InitialiseUFOs(&inst.radar);
		RADAR_Initialise(&(inst.radar), 0.0f, 0.0f, 1.0f, qtrue);
		if (inst.installationStatus == INSTALLATION_WORKING) {
			RADAR_UpdateInstallationRadarCoverage(&inst, inst.installationTemplate->radarRange, inst.installationTemplate->trackingRange);
			/* UFO Yard */
			inst.ufoCapacity.max = inst.installationTemplate->maxUFOsStored;
		} else {
			inst.ufoCapacity.max = 0;
		}
		inst.ufoCapacity.cur = 0;

		/* read battery slots */
		ss = XML_GetNode(s, SAVE_INSTALLATION_BATTERIES);
		if (!ss) {
			Com_Printf("INS_LoadXML: Batteries not defined!\n");
			success = qfalse;
			break;
		}
		inst.numBatteries = XML_GetInt(ss, SAVE_INSTALLATION_NUM, 0);
		if (inst.numBatteries > inst.installationTemplate->maxBatteries) {
			Com_Printf("Installation has more batteries than possible, using upper bound\n");
			inst.numBatteries = inst.installationTemplate->maxBatteries;
		}

		instp = (installation_t*)(LIST_Add(&ccs.installations, (void*)&inst, sizeof(inst)))->data;
		BDEF_InitialiseInstallationSlots(instp);
		B_LoadBaseSlotsXML(instp->batteries, instp->numBatteries, ss);
	}
	Com_UnregisterConstList(saveInstallationConstants);
	Cvar_Set("mn_installation_count", va("%i", INS_GetCount()));

	return success;
}