예제 #1
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;
}
예제 #2
0
/**
 * @brief Show information about item/aircaft/ugv in the market
 */
static void BS_ShowInfo_f (void)
{
	const char* itemid;
	const aircraft_t* aircraft;
	const ugv_t* ugv;
	const objDef_t* od;

	if (cgi->Cmd_Argc() < 2) {
		cgi->Com_Printf("Usage: %s <item-id>\n", cgi->Cmd_Argv(0));
		return;
	}

	itemid = cgi->Cmd_Argv(1);

	if (char const* const rest = Q_strstart(itemid, "aircraft_")) {
		/* PHALANX aircraft - with aircraft golbal idx */
		int idx = atoi(rest);
		aircraft = AIR_AircraftGetFromIDX(idx);

		if (!aircraft) {
			cgi->Com_Printf("Invalid aircraft index!\n");
			return;
		}
		/** @todo show specialized info about PHALANX aircraft */
		BS_MarketAircraftDescription(aircraft->tpl);
		return;
	}

	if (char const* const rest = Q_strstart(itemid, "ugv-")) {
		/* PHALANX ugv - with unique character number index */
		int ucn = atoi(rest);
		Employee* robot = E_GetEmployeeByTypeFromChrUCN(EMPL_ROBOT, ucn);

		if (!robot) {
			cgi->Com_Printf("Invalid UCN for UGV!\n");
			return;
		}

		/** @todo show specialized info about PHLANX UGVs */
		UP_UGVDescription(robot->getUGV());
		return;
	}

	aircraft = AIR_GetAircraftSilent(itemid);
	if (aircraft) {
		BS_MarketAircraftDescription(aircraft->tpl);
		return;
	}

	ugv = cgi->Com_GetUGVByIDSilent(itemid);
	if (ugv) {
		UP_UGVDescription(ugv);
		return;
	}

	/* item */
	od = INVSH_GetItemByID(cgi->Cmd_Argv(1));
	if (od) {
		if (!BS_IsOnMarket(od))
			return;

		if (od->craftitem.type != MAX_ACITEMS)
			UP_AircraftItemDescription(od);
		else
			cgi->INV_ItemDescription(od);
		return;
	}
	cgi->Com_Printf("Invalid item ID\n");
}
예제 #3
0
/**
 * @brief Buy/Sell item/aircraft/ugv on the market
 */
static void BS_Buy_f (void)
{
	const char* itemid;
	int count;
	base_t* base = B_GetCurrentSelectedBase();
	const aircraft_t* aircraft;
	const ugv_t* ugv;
	const objDef_t* od;

	if (cgi->Cmd_Argc() < 2) {
		cgi->Com_Printf("Usage: %s <item-id> <count> [base-idx] \nNegative count means selling. If base index is omitted buys on the currently selected base.\n",
				cgi->Cmd_Argv(0));
		return;
	}

	itemid = cgi->Cmd_Argv(1);
	count = atoi(cgi->Cmd_Argv(2));

	if (cgi->Cmd_Argc() >= 4)
		base = B_GetFoundedBaseByIDX(atoi(cgi->Cmd_Argv(3)));

	if (char const* const rest = Q_strstart(itemid, "aircraft_")) {
		/* aircraft sell - with aircraft golbal idx */
		int idx = atoi(rest);
		aircraft_t* aircraft = AIR_AircraftGetFromIDX(idx);

		if (!aircraft) {
			cgi->Com_Printf("Invalid aircraft index!\n");
			return;
		}
		AIR_RemoveEmployees(*aircraft);
		BS_SellAircraft(aircraft);
		return;
	}

	if (char const* const rest = Q_strstart(itemid, "ugv-")) {
		/* ugv sell - with unique character number index */
		int ucn = atoi(rest);
		Employee* robot = E_GetEmployeeByTypeFromChrUCN(EMPL_ROBOT, ucn);

		if (!robot) {
			cgi->Com_Printf("Invalid UCN for UGV!\n");
			return;
		}

		BS_SellUGV(robot);
		return;
	}

	if (!base) {
		cgi->Com_Printf("No/invalid base selected.\n");
		return;
	}

	aircraft = AIR_GetAircraftSilent(itemid);
	if (aircraft) {
		if (!B_GetBuildingStatus(base, B_COMMAND)) {
			CP_Popup(_("Note"), _("No Command Centre in this base.\nHangars are not functional.\n"));
			return;
		}
		/* We cannot buy aircraft if there is no power in our base. */
		if (!B_GetBuildingStatus(base, B_POWER)) {
			CP_Popup(_("Note"), _("No power supplies in this base.\nHangars are not functional."));
			return;
		}
		/* We cannot buy aircraft without any hangar. */
		if (!AIR_AircraftAllowed(base)) {
			CP_Popup(_("Note"), _("Build a hangar first."));
			return;
		}
		/* Check free space in hangars. */
		if (CAP_GetFreeCapacity(base, AIR_GetHangarCapacityType(aircraft)) <= 0) {
			CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough space in hangars.\n"));
			return;
		}

		if (ccs.credits < BS_GetAircraftBuyingPrice(aircraft)) {
			CP_Popup(_("Notice"), _("You cannot buy this aircraft.\nNot enough credits.\n"));
			return;
		}

		BS_BuyAircraft(aircraft, base);
		return;
	}

	ugv = cgi->Com_GetUGVByIDSilent(itemid);
	if (ugv) {
		const objDef_t* ugvWeapon = INVSH_GetItemByID(ugv->weapon);
		if (!ugvWeapon)
			cgi->Com_Error(ERR_DROP, "BS_BuyItem_f: Could not get weapon '%s' for ugv/tank '%s'.", ugv->weapon, ugv->id);

		if (E_CountUnhiredRobotsByType(ugv) < 1)
			return;
		if (ccs.eMarket.numItems[ugvWeapon->idx] < 1)
			return;

		if (ccs.credits < ugv->price) {
			CP_Popup(_("Not enough money"), _("You cannot buy this item as you don't have enough credits."));
			return;
		}

		if (CAP_GetFreeCapacity(base, CAP_ITEMS) < UGV_SIZE + ugvWeapon->size) {
			CP_Popup(_("Not enough storage space"), _("You cannot buy this item.\nNot enough space in storage.\nBuild more storage facilities."));
			return;
		}

		BS_BuyUGV(ugv, base);
		return;
	}

	if (count == 0) {
		cgi->Com_Printf("Invalid number of items to buy/sell: %s\n", cgi->Cmd_Argv(2));
		return;
	}

	/* item */
	od = INVSH_GetItemByID(cgi->Cmd_Argv(1));
	if (od) {
		if (!BS_IsOnMarket(od))
			return;

		if (count > 0) {
			/* buy */
			const int price = BS_GetItemBuyingPrice(od);
			count = std::min(count, BS_GetItemOnMarket(od));

			/* no items available on market */
			if (count <= 0)
				return;

			if (price <= 0) {
				cgi->Com_Printf("Item on market with invalid buying price: %s (%d)\n", od->id, BS_GetItemBuyingPrice(od));
				return;
			}
			/** @todo warn if player can buy less item due to available credits? */
			count = std::min(count, ccs.credits / price);
			/* not enough money for a single item */
			if (count <= 0) {
				CP_Popup(_("Not enough money"), _("You cannot buy this item as you don't have enough credits."));
				return;
			}

			if (od->size <= 0) {
				cgi->Com_Printf("Item on market with invalid size: %s (%d)\n", od->id, od->size);
				return;
			}
			count = std::min(count, CAP_GetFreeCapacity(base, CAP_ITEMS) / od->size);
			if (count <= 0) {
				CP_Popup(_("Not enough storage space"), _("You cannot buy this item.\nNot enough space in storage.\nBuild more storage facilities."));
				return;
			}

			BS_BuyItem(od, base, count);
		} else {
			/* sell */
			count = std::min(-1 * count, B_ItemInBase(od, base));
			/* no items in storage */
			if (count <= 0)
				return;
			BS_SellItem(od, base, count);
		}
		return;
	}
	cgi->Com_Printf("Invalid item ID\n");
}