예제 #1
0
파일: cp_ufopedia.cpp 프로젝트: cigo/ufoai
/**
 * @brief Prints the description for robots/ugvs.
 * @param[in] ugvType What type of robot/ugv to print the description for.
 * @sa BS_MarketClick_f
 * @sa UP_Article
 */
void UP_UGVDescription (const ugv_t* ugvType)
{
	static char itemText[512];
	const technology_t* tech;

	assert(ugvType);

	tech = RS_GetTechByProvided(ugvType->id);
	assert(tech);

	cgi->INV_ItemDescription(nullptr);

	/* Set name of ugv/robot */
	cgi->Cvar_Set("mn_itemname", "%s", _(tech->name));
	cgi->Cvar_Set("mn_item", "%s", tech->provides);

	cgi->Cvar_Set("mn_upmetadata", "1");
	if (RS_IsResearched_ptr(tech)) {
		/** @todo make me shiny */
		Com_sprintf(itemText, sizeof(itemText), _("%s\n%s"), _(tech->name), ugvType->weapon);
	} else if (RS_Collected_(tech)) {
		/** @todo Display crippled info and pre-research text here */
		Com_sprintf(itemText, sizeof(itemText), _("Unknown - need to research this"));
	} else {
		Com_sprintf(itemText, sizeof(itemText), _("Unknown - need to research this"));
	}
	cgi->UI_RegisterText(TEXT_ITEMDESCRIPTION, itemText);
}
/**
 * @brief Opens the UFOpedia for the current selected item/aircraft.
 * @note called by market_openpedia
 */
static void BS_MarketInfoClick_f (void)
{
	const technology_t *tech = RS_GetTechByProvided(Cvar_GetString("mn_item"));

	if (tech)
		UP_OpenWith(tech->id);
}
예제 #3
0
파일: cp_airfight.cpp 프로젝트: yason/ufoai
/**
 * @brief Load callback for savegames in XML Format
 * @param[in] parent XML Node structure, where we get the information from
 */
bool AIRFIGHT_LoadXML (xmlNode_t* parent)
{
	int i;
	xmlNode_t* node;

	for (i = 0, node = cgi->XML_GetNode(parent, SAVE_AIRFIGHT_PROJECTILE); i < MAX_PROJECTILESONGEOSCAPE && node;
			node = cgi->XML_GetNextNode(node, parent, SAVE_AIRFIGHT_PROJECTILE), i++) {
		technology_t* tech = RS_GetTechByProvided(cgi->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 false;
		}

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

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

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

		if ((attackingAircraft = cgi->XML_GetNode(node, SAVE_AIRFIGHT_ATTACKINGAIRCRAFT))) {
			if (cgi->XML_GetBool(attackingAircraft, SAVE_AIRFIGHT_ISUFO, false))
				/** @todo 0 as default might be incorrect */
				projectile->attackingAircraft = UFO_GetByIDX(cgi->XML_GetInt(attackingAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, 0));
			else
				projectile->attackingAircraft = AIR_AircraftGetFromIDX(cgi->XML_GetInt(attackingAircraft, SAVE_AIRFIGHT_AIRCRAFTIDX, AIRCRAFT_INVALID));
		} else {
			projectile->attackingAircraft = nullptr;
		}
		cgi->XML_GetPos3(node, SAVE_AIRFIGHT_ATTACKERPOS, projectile->attackerPos);

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

	return true;
}
예제 #4
0
/**
 * @brief Copies an entry from the building description file into the list of building types.
 * @note Parses one "building" entry in the basemanagement.ufo file and writes
 * it into the next free entry in bmBuildings[0], which is the list of buildings
 * in the first base (building_t).
 * @param[in] name Unique script id of a building. This is parsed from "building xxx" -> id=xxx.
 * @param[in] text the whole following text that is part of the "building" item definition in .ufo.
 * @param[in] link Bool value that decides whether to link the tech pointer in or not
 * @sa CL_ParseScriptFirst (link is false here)
 * @sa CL_ParseScriptSecond (link it true here)
 */
void B_ParseBuildings (const char *name, const char **text, bool link)
{
	building_t *building;
	technology_t *techLink;
	const char *errhead = "B_ParseBuildings: unexpected end of file (names ";
	const char *token;

	/* get id list body */
	token = Com_Parse(text);
	if (!*text || *token != '{') {
		Com_Printf("B_ParseBuildings: building \"%s\" without body ignored\n", name);
		return;
	}

	if (ccs.numBuildingTemplates >= MAX_BUILDINGS)
		cgi->Com_Error(ERR_DROP, "B_ParseBuildings: too many buildings");

	if (!link) {
		int i;
		for (i = 0; i < ccs.numBuildingTemplates; i++) {
			if (Q_streq(ccs.buildingTemplates[i].id, name)) {
				Com_Printf("B_ParseBuildings: Second building with same name found (%s) - second ignored\n", name);
				return;
			}
		}

		/* new entry */
		building = &ccs.buildingTemplates[ccs.numBuildingTemplates];
		OBJZERO(*building);
		building->id = Mem_PoolStrDup(name, cp_campaignPool, 0);

		Com_DPrintf(DEBUG_CLIENT, "...found building %s\n", building->id);

		/* set standard values */
		building->tpl = building;	/* Self-link just in case ... this way we can check if it is a template or not. */
		building->idx = -1;			/* No entry in buildings list (yet). */
		building->base = NULL;
		building->buildingType = MAX_BUILDING_TYPE;
		building->dependsBuilding = NULL;
		building->maxCount = -1;	/* Default: no limit */
		building->size[0] = 1;
		building->size[1] = 1;

		ccs.numBuildingTemplates++;
		do {
			/* get the name type */
			token = cgi->Com_EParse(text, errhead, name);
			if (!*text)
				break;
			if (*token == '}')
				break;

			/* get values */
			if (Q_streq(token, "type")) {
				token = cgi->Com_EParse(text, errhead, name);
				if (!*text)
					return;

				building->buildingType = B_GetBuildingTypeByBuildingID(token);
				if (building->buildingType >= MAX_BUILDING_TYPE)
					Com_Printf("didn't find buildingType '%s'\n", token);
			} else {
				/* no linking yet */
				if (Q_streq(token, "depends")) {
					cgi->Com_EParse(text, errhead, name);
					if (!*text)
						return;
				} else {
					if (!Com_ParseBlockToken(name, text, building, valid_building_vars, cp_campaignPool, token))
						Com_Printf("B_ParseBuildings: unknown token \"%s\" ignored (building %s)\n", token, name);
				}
			}
		} while (*text);
		if (building->size[0] < 1 || building->size[1] < 1 || building->size[0] >= BASE_SIZE || building->size[1] >= BASE_SIZE) {
			Com_Printf("B_ParseBuildings: Invalid size for building %s (%i, %i)\n", building->id, (int)building->size[0], (int)building->size[1]);
			ccs.numBuildingTemplates--;
		}
	} else {
		building = B_GetBuildingTemplate(name);
		if (!building)
			cgi->Com_Error(ERR_DROP, "B_ParseBuildings: Could not find building with id %s\n", name);

		techLink = RS_GetTechByProvided(name);
		if (techLink)
			building->tech = techLink;

		do {
			/* get the name type */
			token = cgi->Com_EParse(text, errhead, name);
			if (!*text)
				break;
			if (*token == '}')
				break;
			/* get values */
			if (Q_streq(token, "depends")) {
				const building_t *dependsBuilding = B_GetBuildingTemplate(cgi->Com_EParse(text, errhead, name));
				if (!dependsBuilding)
					cgi->Com_Error(ERR_DROP, "Could not find building depend of %s\n", building->id);
				building->dependsBuilding = dependsBuilding;
				if (!*text)
					return;
			}
		} while (*text);
	}
}
예제 #5
0
/**
 * @brief Fill market item list
 */
static void BS_FillMarket_f (void)
{
	const base_t* base = B_GetCurrentSelectedBase();
	itemFilterTypes_t type;

	if (cgi->Cmd_Argc() < 2) {
		cgi->Com_Printf("Usage: %s <category>\n", cgi->Cmd_Argv(0));
		return;
	}
	if (cgi->Cmd_Argc() >= 3)
		base = B_GetFoundedBaseByIDX(atoi(cgi->Cmd_Argv(2)));
	if (!base) {
		cgi->Com_Printf("No/invalid base selected.\n");
		return;
	}

	type = cgi->INV_GetFilterTypeID(cgi->Cmd_Argv(1));
	cgi->UI_ExecuteConfunc("ui_market_clear");
	switch (type) {
	case FILTER_UGVITEM:
		/* show own UGV */
		E_Foreach(EMPL_ROBOT, robot) {
			const ugv_t* ugv = robot->getUGV();
			const technology_t* tech = RS_GetTechByProvided(ugv->id);

			if (!robot->isHiredInBase(base))
				continue;

			cgi->UI_ExecuteConfunc("ui_market_add \"ugv-%d\" \"%s\" 1 0 0 %d - \"%s\"", robot->chr.ucn, _(tech->name), ugv->price, robot->isAwayFromBase() ? _("UGV is away from home") : "-");
		}
		/* show buyable UGV */
		for (int i = 0; i < cgi->csi->numUGV; i++) {
			const ugv_t* ugv = &cgi->csi->ugvs[i];
			const technology_t* tech = RS_GetTechByProvided(ugv->id);
			const objDef_t* ugvWeapon = INVSH_GetItemByID(ugv->weapon);
			const int buyable = std::min(E_CountUnhiredRobotsByType(ugv), BS_GetItemOnMarket(ugvWeapon));

			assert(tech);
			if (!RS_IsResearched_ptr(tech))
				continue;
			if (buyable <= 0)
				continue;

			cgi->UI_ExecuteConfunc("ui_market_add %s \"%s\" 0 %d %d %d - -", ugv->id, _(tech->name), buyable, ugv->price, ugv->price);
		}
		/* show (UGV) items, fall through */
	case FILTER_S_PRIMARY:
	case FILTER_S_SECONDARY:
	case FILTER_S_HEAVY:
	case FILTER_S_IMPLANT:
	case FILTER_S_MISC:
	case FILTER_S_ARMOUR:
	case FILTER_DUMMY:
	case FILTER_CRAFTITEM:
	case MAX_FILTERTYPES: {
		for (int i = 0; i < cgi->csi->numODs; i++) {
			const objDef_t* od = &cgi->csi->ods[i];
			const technology_t* tech = RS_GetTechForItem(od);

			if (!BS_IsOnMarket(od))
				continue;
			if (B_ItemInBase(od, base) + BS_GetItemOnMarket(od) <= 0)
				continue;
			if (type != MAX_FILTERTYPES && !cgi->INV_ItemMatchesFilter(od, type))
				continue;
			cgi->UI_ExecuteConfunc("ui_market_add %s \"%s\" %d %d %d %d %s -", od->id, _(od->name), B_ItemInBase(od, base), BS_GetItemOnMarket(od), BS_GetItemBuyingPrice(od), BS_GetItemSellingPrice(od), RS_IsResearched_ptr(tech) ? va("%d", ccs.eMarket.autosell[i]) : "-");
		}
		break;
	}
	case FILTER_AIRCRAFT: {
		AIR_ForeachFromBase(aircraft, base) {
			cgi->UI_ExecuteConfunc("ui_market_add \"aircraft_%d\" \"%s\" 1 0 0 %d - \"%s\"", aircraft->idx, aircraft->name, BS_GetAircraftSellingPrice(aircraft), AIR_IsAircraftInBase(aircraft) ? "-" : _("Aircraft is away from home"));
		}
		for (int i = 0; i < ccs.numAircraftTemplates; i++) {
			const aircraft_t* aircraft = &ccs.aircraftTemplates[i];
			if (!BS_AircraftIsOnMarket(aircraft))
				continue;
			if (!RS_IsResearched_ptr(aircraft->tech))
				continue;
			if (BS_GetAircraftOnMarket(aircraft) <= 0)
				continue;
			cgi->UI_ExecuteConfunc("ui_market_add \"%s\" \"%s\" 0 %d %d %d - -", aircraft->id, _(aircraft->tech->name), BS_GetAircraftOnMarket(aircraft), BS_GetAircraftBuyingPrice(aircraft), BS_GetAircraftSellingPrice(aircraft));
		}
		break;
	}
	default:
		break;
	}
예제 #6
0
/**
 * @brief Get the technology for a given UFO type
 * @param type UFO type to get the technology for
 * @return The technology for the given UFO. If no technology was found for the UFO
 * id this might return @c NULL.
 */
const technology_t* UFO_GetTechnologyFromType (const ufoType_t type)
{
	const char *id = Com_UFOTypeToShortName(type);
	const technology_t *tech = RS_GetTechByProvided(id);
	return tech;
}