/**
 * Shows the selected soldier's info.
 * @param action Pointer to an action.
 */
void CraftSoldiersState::lstSoldiersClick(Action *action)
{
	int row = _lstSoldiers->getSelectedRow();
	Craft *c = _base->getCrafts()->at(_craft);
	Soldier *s = _base->getSoldiers()->at(_lstSoldiers->getSelectedRow());
	Uint8 color = Palette::blockOffset(13)+10;
	if (s->getCraft() == c)
	{
		s->setCraft(0);
		_lstSoldiers->setCellText(row, 2, _game->getLanguage()->getString("STR_NONE_UC"));
		color = Palette::blockOffset(13)+10;
	}
	else if (c->getRules()->getSoldiers() - c->getNumSoldiers() > 0)
	{
		s->setCraft(c);
		_lstSoldiers->setCellText(row, 2, c->getName(_game->getLanguage()));
		color = Palette::blockOffset(13);
	}
	_lstSoldiers->setRowColor(row, color);

	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_SPACE_AVAILABLE") << L'\x01' << c->getRules()->getSoldiers() - c->getNumSoldiers();
	_txtAvailable->setText(ss.str());
	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_SPACE_USED") << L'\x01' << c->getNumSoldiers();
	_txtUsed->setText(ss2.str());
}
/**
 * Displays the inventory screen for the soldiers
 * inside the craft.
 * @param action Pointer to an action.
 */
void CraftEquipmentState::btnInventoryClick(Action *)
{
	Craft *craft = _base->getCrafts()->at(_craft);
	if (craft->getNumSoldiers() != 0)
	{
		SavedBattleGame *bgame = new SavedBattleGame();
		_game->getSavedGame()->setBattleGame(bgame);

		BattlescapeGenerator bgen = BattlescapeGenerator(_game);
		bgen.runInventory(craft);

		_game->getScreen()->clear();
		_game->pushState(new InventoryState(false, 0));
	}
}
Exemple #3
0
/**
* Displays the inventory screen for the soldiers
* inside the craft.
* @param action Pointer to an action.
*/
void CraftEquipmentState::btnInventoryClick(Action *)
{
	Craft *craft = _base->getCrafts()->at(_craft);
	if (craft->getNumSoldiers() == 0)
	{
		std::wstringstream ss;
		ss << craft->getName(_game->getLanguage()) << L'\n' << tr("STR_NO_CREW");
		_game->pushState(new ErrorMessageState(_game, ss.str(), Palette::blockOffset(15)+1, "BACK04.SCR", 2));
	}
	else
	{
		_game->setPalette(_game->getResourcePack()->getPalette("PALETTES.DAT_4")->getColors());

		SavedBattleGame *bgame = new SavedBattleGame();
		_game->getSavedGame()->setBattleGame(bgame);

		BattlescapeGenerator bgen = BattlescapeGenerator(_game);
		bgen.runInventory(craft);

		_game->pushState(new InventoryState(_game, false, 0));
	}
}
/**
 * Initializes all the elements in the Craft Equipment screen.
 * @param game Pointer to the core game.
 * @param base Pointer to the base to get info from.
 * @param craft ID of the selected craft.
 */
CraftEquipmentState::CraftEquipmentState(Game *game, Base *base, size_t craft) : State(game), _sel(0), _base(base), _craft(craft)
{
	bool allowChangeListValuesByMouseWheel=Options::getBool("allowChangeListValuesByMouseWheel");
	_changeValueByMouseWheel = Options::getInt("changeValueByMouseWheel");

	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton(288, 16, 16, 176);
	_txtTitle = new Text(300, 16, 16, 7);
	_txtItem = new Text(144, 9, 16, 32);
	_txtStores = new Text(150, 9, 160, 32);
	_txtAvailable = new Text(110, 9, 16, 24);
	_txtUsed = new Text(110, 9, 130, 24);
	_txtCrew = new Text(71, 9, 244, 24);
	_lstEquipment = new TextList(288, 128, 8, 40);

	// Set palette
	_game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(2)), Palette::backPos, 16);

	add(_window);
	add(_btnOk);
	add(_txtTitle);
	add(_txtItem);
	add(_txtStores);
	add(_txtAvailable);
	add(_txtUsed);
	add(_txtCrew);
	add(_lstEquipment);

	// Set up objects
	_window->setColor(Palette::blockOffset(15)+1);
	_window->setBackground(_game->getResourcePack()->getSurface("BACK04.SCR"));

	_btnOk->setColor(Palette::blockOffset(15)+1);
	_btnOk->setText(_game->getLanguage()->getString("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&CraftEquipmentState::btnOkClick);

	_txtTitle->setColor(Palette::blockOffset(15)+1);
	_txtTitle->setBig();
	Craft *c = _base->getCrafts()->at(_craft);
	_txtTitle->setText(tr("STR_EQUIPMENT_FOR_craftname").arg(c->getName(_game->getLanguage())));

	_txtItem->setColor(Palette::blockOffset(15)+1);
	_txtItem->setText(_game->getLanguage()->getString("STR_ITEM"));

	_txtStores->setColor(Palette::blockOffset(15)+1);
	_txtStores->setText(_game->getLanguage()->getString("STR_STORES"));

	_txtAvailable->setColor(Palette::blockOffset(15)+1);
	_txtAvailable->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_SPACE_AVAILABLE") << L'\x01'<< c->getSpaceAvailable();
	_txtAvailable->setText(ss.str());

	_txtUsed->setColor(Palette::blockOffset(15)+1);
	_txtUsed->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_SPACE_USED") << L'\x01'<< c->getSpaceUsed();
	_txtUsed->setText(ss2.str());

	_txtCrew->setColor(Palette::blockOffset(15)+1);
	_txtCrew->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss3;
	ss3 << _game->getLanguage()->getString("STR_SOLDIERS_UC") << ">" << L'\x01'<< c->getNumSoldiers();
	_txtCrew->setText(ss3.str());

	_lstEquipment->setColor(Palette::blockOffset(13)+10);
	_lstEquipment->setArrowColor(Palette::blockOffset(15)+1);
	_lstEquipment->setArrowColumn(203, ARROW_HORIZONTAL);
	_lstEquipment->setColumns(3, 154, 85, 41);
	_lstEquipment->setSelectable(true);
	_lstEquipment->setBackground(_window);
	_lstEquipment->setMargin(8);
	if (allowChangeListValuesByMouseWheel) _lstEquipment->setAllowScrollOnArrowButtons(false);
	_lstEquipment->onLeftArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowPress);
	_lstEquipment->onLeftArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowRelease);
	_lstEquipment->onLeftArrowClick((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowClick);
	_lstEquipment->onRightArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowPress);
	_lstEquipment->onRightArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowRelease);
	_lstEquipment->onRightArrowClick((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowClick);
	if (allowChangeListValuesByMouseWheel) _lstEquipment->onMousePress((ActionHandler)&CraftEquipmentState::lstEquipmentMousePress);

	int row = 0;
	const std::vector<std::string> &items = _game->getRuleset()->getItemsList();
	for (std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i)
	{
		// CHEAP HACK TO HIDE HWP AMMO
		if ((*i).substr(0, 8) == "STR_HWP_")
			continue;

		RuleItem *rule = _game->getRuleset()->getItem(*i);
		int cQty = 0;
		if (rule->isFixed())
		{
			cQty = c->getVehicleCount(*i);
		}
		else
		{
			cQty = c->getItems()->getItem(*i);
		}
		if (rule->getBigSprite() > -1 && rule->getBattleType() != BT_NONE && rule->getBattleType() != BT_CORPSE &&
			_game->getSavedGame()->isResearched(rule->getRequirements()) &&
			(_base->getItems()->getItem(*i) > 0 || cQty > 0))
		{
			_items.push_back(*i);
			std::wstringstream ss, ss2;
			ss << _base->getItems()->getItem(*i);
			ss2 << cQty;

			std::wstring s = _game->getLanguage()->getString(*i);
			if (rule->getBattleType() == BT_AMMO)
			{
				s.insert(0, L"  ");
			}
			_lstEquipment->addRow(3, s.c_str(), ss.str().c_str(), ss2.str().c_str());

			Uint8 color;
			if (cQty == 0)
			{
				if (rule->getBattleType() == BT_AMMO)
				{
					color = Palette::blockOffset(15)+6;
				}
				else
				{
					color = Palette::blockOffset(13)+10;
				}
			}
			else
			{
				color = Palette::blockOffset(13);
			}
			_lstEquipment->setRowColor(row, color);

			++row;
		}
	}

	_timerLeft = new Timer(50);
	_timerLeft->onTimer((StateHandler)&CraftEquipmentState::moveLeft);
	_timerRight = new Timer(50);
	_timerRight->onTimer((StateHandler)&CraftEquipmentState::moveRight);
}
/**
 * The craft info can change
 * after going into other screens.
 */
void CraftInfoState::init()
{
    // Set palette
    _game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(3)), Palette::backPos, 16);

    Craft *c = _base->getCrafts()->at(_craft);

    _edtCraft->setText(c->getName(_game->getLanguage()));

    SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK");
    texture->getFrame(c->getRules()->getSprite() + 33)->setX(0);
    texture->getFrame(c->getRules()->getSprite() + 33)->setY(0);
    texture->getFrame(c->getRules()->getSprite() + 33)->blit(_sprite);

    std::wstringstream ss;
    ss << tr("STR_DAMAGE_UC_").arg(Text::formatPercentage(c->getDamagePercentage()));
    if (c->getStatus() == "STR_REPAIRS")
    {
        int damageDays = (int)ceil((float)c->getDamage() / c->getRules()->getRepairRate() / 24.0f);
        ss << L"\n(" << tr("STR_DAY", damageDays) << ")";
    }
    _txtDamage->setText(ss.str());

    std::wstringstream ss2;
    ss2 << tr("STR_FUEL").arg(Text::formatPercentage(c->getFuelPercentage()));
    if (c->getStatus() == "STR_REFUELLING")
    {
        int fuelDays = (int) ceil((float)(c->getRules()->getMaxFuel() - c->getFuel()) / c->getRules()->getRefuelRate() / 48.0f);
        ss2 << L"\n(" << tr("STR_DAY", fuelDays) << ")";
    }
    _txtFuel->setText(ss2.str());

    if (c->getRules()->getSoldiers() > 0)
    {
        _crew->clear();
        _equip->clear();

        Surface *frame1 = texture->getFrame(38);
        frame1->setY(0);
        for (int i = 0, x = 0; i < c->getNumSoldiers(); ++i, x += 10)
        {
            frame1->setX(x);
            frame1->blit(_crew);
        }

        Surface *frame2 = texture->getFrame(40);
        frame2->setY(0);
        int x = 0;
        for (int i = 0; i < c->getNumVehicles(); ++i, x += 10)
        {
            frame2->setX(x);
            frame2->blit(_equip);
        }
        Surface *frame3 = texture->getFrame(39);
        for (int i = 0; i < c->getNumEquipment(); i += 4, x += 10)
        {
            frame3->setX(x);
            frame3->blit(_equip);
        }
    }
    else
    {
        _crew->setVisible(false);
        _equip->setVisible(false);
        _btnCrew->setVisible(false);
        _btnEquip->setVisible(false);
        _btnArmor->setVisible(false);
    }

    if (c->getRules()->getWeapons() > 0)
    {
        CraftWeapon *w1 = c->getWeapons()->at(0);

        if (w1 != 0)
        {
            Surface *frame = texture->getFrame(w1->getRules()->getSprite() + 48);
            frame->setX(0);
            frame->setY(0);
            frame->blit(_weapon1);

            _txtW1Name->setText(tr(w1->getRules()->getType()));
            _txtW1Ammo->setText(tr("STR_AMMO_").arg(w1->getAmmo()));
            _txtW1Max->setText(tr("STR_MAX").arg(w1->getRules()->getAmmoMax()));
        }
        else
        {
            _weapon1->clear();
            _txtW1Name->setText(L"");
            _txtW1Ammo->setText(L"");
            _txtW1Max->setText(L"");
        }
    }
    else
    {
        _weapon1->setVisible(false);
        _btnW1->setVisible(false);
        _txtW1Name->setVisible(false);
        _txtW1Ammo->setVisible(false);
        _txtW1Max->setVisible(false);
    }

    if (c->getRules()->getWeapons() > 1)
    {
        CraftWeapon *w2 = c->getWeapons()->at(1);

        if (w2 != 0)
        {
            Surface *frame = texture->getFrame(w2->getRules()->getSprite() + 48);
            frame->setX(0);
            frame->setY(0);
            frame->blit(_weapon2);

            _txtW2Name->setText(tr(w2->getRules()->getType()));
            _txtW2Ammo->setText(tr("STR_AMMO_").arg(w2->getAmmo()));
            _txtW2Max->setText(tr("STR_MAX").arg(w2->getRules()->getAmmoMax()));
        }
        else
        {
            _weapon2->clear();
            _txtW2Name->setText(L"");
            _txtW2Ammo->setText(L"");
            _txtW2Max->setText(L"");
        }
    }
    else
    {
        _weapon2->setVisible(false);
        _btnW2->setVisible(false);
        _txtW2Name->setVisible(false);
        _txtW2Ammo->setVisible(false);
        _txtW2Max->setVisible(false);
    }
}
Exemple #6
0
/**
 * This function is called when one of the mission's UFOs arrives at it's current destination.
 * It takes care of sending the UFO to the next waypoint, landing UFOs and
 * marking them for removal as required. It must set the game data in a way that the rest of the code
 * understands what to do.
 * @param ufo The UFO that reached it's waypoint.
 * @param engine The game engine, required to get access to game data and game rules.
 * @param globe The earth globe, required to get access to land checks.
 */
void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe)
{
	const Ruleset &rules = *engine.getRuleset();
	SavedGame &game = *engine.getSavedGame();
	if (ufo.getTrajectoryPoint() == ufo.getTrajectory().getWaypointCount() - 1)
	{
		ufo.setDetected(false);
		ufo.setStatus(Ufo::DESTROYED);
		return;
	}
	ufo.setAltitude(ufo.getTrajectory().getAltitude(ufo.getTrajectoryPoint() + 1));
	if (ufo.getAltitude() != "STR_GROUND")
	{
		if (ufo.getLandId() != 0)
		{
			ufo.setLandId(0);
		}
		ufo.setTrajectoryPoint(ufo.getTrajectoryPoint() + 1);
		// Set next waypoint.
		Waypoint *wp = new Waypoint();
		RuleRegion *region = rules.getRegion(_region);
		ufo.setSpeed((int)(ufo.getRules()->getMaxSpeed() * ufo.getTrajectory().getSpeedPercentage(ufo.getTrajectoryPoint())));
		std::pair<double, double> pos;
		if (ufo.getTrajectory().getAltitude(ufo.getTrajectoryPoint()) == "STR_GROUND")
		{
			pos = getLandPoint(globe, *region, ufo.getTrajectory().getZone(ufo.getTrajectoryPoint()));
		}
		else
		{
			pos = region->getRandomPoint(ufo.getTrajectory().getZone(ufo.getTrajectoryPoint()));
		}
		wp->setLongitude(pos.first);
		wp->setLatitude(pos.second);
		ufo.setDestination(wp);
	}
	else
	{
		// UFO landed.

		if (ufo.getRules()->getType() == "STR_TERROR_SHIP" && _rule.getType() == "STR_ALIEN_TERROR" && ufo.getTrajectory().getZone(ufo.getTrajectoryPoint()) == 0)
		{
			// Specialized: STR_ALIEN_TERROR
			// Remove UFO, replace with TerrorSite.
			addScore(ufo.getLongitude(), ufo.getLatitude(), engine);
			ufo.setStatus(Ufo::DESTROYED);
			TerrorSite *terrorSite = new TerrorSite();
			terrorSite->setLongitude(ufo.getLongitude());
			terrorSite->setLatitude(ufo.getLatitude());
			terrorSite->setId(game.getId("STR_TERROR_SITE"));
			terrorSite->setSecondsRemaining(4 * 3600 + RNG::generate(0, 6) * 3600);
			terrorSite->setAlienRace(_race);
			const City *city = rules.locateCity(ufo.getLongitude(), ufo.getLatitude());
			assert(city);
			game.getTerrorSites()->push_back(terrorSite);
			for (std::vector<Target*>::iterator t = ufo.getFollowers()->begin(); t != ufo.getFollowers()->end();)
			{
				Craft* c = dynamic_cast<Craft*>(*t);
				if (c && c->getNumSoldiers() != 0)
				{
					c->setDestination(terrorSite);
					t = ufo.getFollowers()->begin();
				}
				else
				{
					++t;
				}
			}
		}
		else if (_rule.getType() == "STR_ALIEN_RETALIATION" && ufo.getTrajectory().getID() == "__RETALIATION_ASSAULT_RUN")
		{
			// Ignore what the trajectory might say, this is a base assault.
			// Remove UFO, replace with Base defense.
			ufo.setDetected(false);
			std::vector<Base *>::const_iterator found =
			    std::find_if(game.getBases()->begin(), game.getBases()->end(),
					 MatchBaseCoordinates(ufo.getLongitude(), ufo.getLatitude()));
			if (found == game.getBases()->end())
			{
				ufo.setStatus(Ufo::DESTROYED);
				// Only spawn mission if the base is still there.
				return;
			}
			ufo.setDestination(*found);
		}
		else
		{
			// Set timer for UFO on the ground.
			ufo.setSecondsRemaining(ufo.getTrajectory().groundTimer());
			if (ufo.getDetected() && ufo.getLandId() == 0)
			{
				ufo.setLandId(engine.getSavedGame()->getId("STR_LANDING_SITE"));
			}
		}
	}
}
/**
 * Initializes all the elements in the Craft Equipment screen.
 * @param game Pointer to the core game.
 * @param base Pointer to the base to get info from.
 * @param craft ID of the selected craft.
 */
CraftEquipmentState::CraftEquipmentState(Game *game, Base *base, unsigned int craft) : State(game), _sel(0), _base(base), _craft(craft)
{
	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton(288, 16, 16, 176);
	_txtTitle = new Text(300, 16, 16, 7);
	_txtItem = new Text(144, 9, 16, 32);
	_txtStores = new Text(150, 9, 160, 32);
	_txtAvailable = new Text(110, 9, 16, 24);
	_txtUsed = new Text(110, 9, 130, 24);
	_lstEquipment = new TextList(288, 128, 8, 40);

	// Set palette
	_game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(2)), Palette::backPos, 16);

	add(_window);
	add(_btnOk);
	add(_txtTitle);
	add(_txtItem);
	add(_txtStores);
	add(_txtAvailable);
	add(_txtUsed);
	add(_lstEquipment);

	// Set up objects
	_window->setColor(Palette::blockOffset(15)+1);
	_window->setBackground(_game->getResourcePack()->getSurface("BACK04.SCR"));

	_btnOk->setColor(Palette::blockOffset(15)+1);
	_btnOk->setText(_game->getLanguage()->getString("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&CraftEquipmentState::btnOkClick);

	_txtTitle->setColor(Palette::blockOffset(15)+1);
	_txtTitle->setBig();
	Craft *c = _base->getCrafts()->at(_craft);
	std::wstring s;
	s = _game->getLanguage()->getString("STR_EQUIPMENT_FOR") + c->getName(_game->getLanguage());
	_txtTitle->setText(s);

	_txtItem->setColor(Palette::blockOffset(15)+1);
	_txtItem->setText(_game->getLanguage()->getString("STR_ITEM"));

	_txtStores->setColor(Palette::blockOffset(15)+1);
	_txtStores->setText(_game->getLanguage()->getString("STR_STORES"));

	_txtAvailable->setColor(Palette::blockOffset(15)+1);
	_txtAvailable->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_SPACE_AVAILABLE") << L'\x01'<< c->getRules()->getSoldiers() - c->getNumSoldiers();
	_txtAvailable->setText(ss.str());

	_txtUsed->setColor(Palette::blockOffset(15)+1);
	_txtUsed->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_SPACE_USED") << L'\x01'<< c->getNumSoldiers();
	_txtUsed->setText(ss2.str());

	_lstEquipment->setColor(Palette::blockOffset(13)+10);
	_lstEquipment->setArrowColor(Palette::blockOffset(15)+1);
	_lstEquipment->setArrowColumn(203, ARROW_HORIZONTAL);
	_lstEquipment->setColumns(3, 154, 85, 41);
	_lstEquipment->setSelectable(true);
	_lstEquipment->setBackground(_window);
	_lstEquipment->setMargin(8);
	_lstEquipment->onLeftArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowPress);
	_lstEquipment->onLeftArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowRelease);
	_lstEquipment->onRightArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowPress);
	_lstEquipment->onRightArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowRelease);

	_items.push_back("STR_PISTOL");
	_items.push_back("STR_PISTOL_CLIP");
	_items.push_back("STR_RIFLE");
	_items.push_back("STR_RIFLE_CLIP");
	_items.push_back("STR_HEAVY_CANNON");
	_items.push_back("STR_HC_AP_AMMO");
	_items.push_back("STR_HC_HE_AMMO");
	_items.push_back("STR_HC_I_AMMO");
	_items.push_back("STR_AUTO_CANNON");
	_items.push_back("STR_AC_AP_AMMO");
	_items.push_back("STR_AC_HE_AMMO");
	_items.push_back("STR_AC_I_AMMO");
	_items.push_back("STR_ROCKET_LAUNCHER");
	_items.push_back("STR_SMALL_ROCKET");
	_items.push_back("STR_LARGE_ROCKET");
	_items.push_back("STR_INCENDIARY_ROCKET");
	_items.push_back("STR_GRENADE");
	_items.push_back("STR_SMOKE_GRENADE");
	_items.push_back("STR_ELECTRO_FLARE");

	int row = 0;
	for (std::vector<std::string>::iterator i = _items.begin(); i != _items.end();)
	{
		if (_base->getItems()->getItem(*i) == 0 && c->getItems()->getItem(*i) == 0)
		{
			i = _items.erase(i);
		}
		else
		{
			std::wstringstream ss, ss2;
			ss << _base->getItems()->getItem(*i);
			ss2 << c->getItems()->getItem(*i);

			RuleItem *rule = _game->getRuleset()->getItem(*i);
			std::wstring s = _game->getLanguage()->getString(*i);
			if (rule->getBattleType() == BT_AMMO)
			{
				s.insert(0, L"  ");
			}
			_lstEquipment->addRow(3, s.c_str(), ss.str().c_str(), ss2.str().c_str());

			Uint8 color;
			if (c->getItems()->getItem(*i) == 0)
			{
				if (rule->getBattleType() == BT_AMMO)
				{
					color = Palette::blockOffset(15)+6;
				}
				else
				{
					color = Palette::blockOffset(13)+10;
				}
			}
			else
			{
				color = Palette::blockOffset(13);
			}
			_lstEquipment->setRowColor(row, color);

			++i;
			row++;
		}
	}

	_timerLeft = new Timer(50);
	_timerLeft->onTimer((StateHandler)&CraftEquipmentState::moveLeft);
	_timerRight = new Timer(50);
	_timerRight->onTimer((StateHandler)&CraftEquipmentState::moveRight);
}
/**
 * Initializes all the elements in the Craft Equipment screen.
 * @param game Pointer to the core game.
 * @param base Pointer to the base to get info from.
 * @param craft ID of the selected craft.
 */
CraftEquipmentState::CraftEquipmentState(Base *base, size_t craft) : _sel(0), _craft(craft), _base(base), _totalItems(0), _ammoColor(0)
{
	Craft *c = _base->getCrafts()->at(_craft);
	bool craftHasACrew = c->getNumSoldiers() > 0;
	bool isNewBattle = _game->getSavedGame()->getMonthsPassed() == -1;

	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton((craftHasACrew || isNewBattle)? 148:288, 16, (craftHasACrew || isNewBattle)? 164:16, 176);
	_btnClear = new TextButton(148, 16, 8, 176);
	_btnInventory = new TextButton(148, 16, 8, 176);
	_txtTitle = new Text(300, 17, 16, 7);
	_txtItem = new Text(144, 9, 16, 32);
	_txtStores = new Text(150, 9, 160, 32);
	_txtAvailable = new Text(110, 9, 16, 24);
	_txtUsed = new Text(110, 9, 130, 24);
	_txtCrew = new Text(71, 9, 244, 24);
	_lstEquipment = new TextList(288, 128, 8, 40);

	// Set palette
	setInterface("craftEquipment");

	_ammoColor = _game->getMod()->getInterface("craftEquipment")->getElement("ammoColor")->color;

	add(_window, "window", "craftEquipment");
	add(_btnOk, "button", "craftEquipment");
	add(_btnClear, "button", "craftEquipment");
	add(_btnInventory, "button", "craftEquipment");
	add(_txtTitle, "text", "craftEquipment");
	add(_txtItem, "text", "craftEquipment");
	add(_txtStores, "text", "craftEquipment");
	add(_txtAvailable, "text", "craftEquipment");
	add(_txtUsed, "text", "craftEquipment");
	add(_txtCrew, "text", "craftEquipment");
	add(_lstEquipment, "list", "craftEquipment");

	centerAllSurfaces();

	// Set up objects
	_window->setBackground(_game->getMod()->getSurface("BACK04.SCR"));

	_btnOk->setText(tr("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&CraftEquipmentState::btnOkClick);
	_btnOk->onKeyboardPress((ActionHandler)&CraftEquipmentState::btnOkClick, Options::keyCancel);

	_btnClear->setText(tr("STR_UNLOAD_CRAFT"));
	_btnClear->onMouseClick((ActionHandler)&CraftEquipmentState::btnClearClick);
	_btnClear->setVisible(isNewBattle);

	_btnInventory->setText(tr("STR_INVENTORY"));
	_btnInventory->onMouseClick((ActionHandler)&CraftEquipmentState::btnInventoryClick);
	_btnInventory->setVisible(craftHasACrew && !isNewBattle);

	_txtTitle->setBig();
	_txtTitle->setText(tr("STR_EQUIPMENT_FOR_CRAFT").arg(c->getName(_game->getLanguage())));

	_txtItem->setText(tr("STR_ITEM"));

	_txtStores->setText(tr("STR_STORES"));

	_txtAvailable->setText(tr("STR_SPACE_AVAILABLE").arg(c->getSpaceAvailable()));

	_txtUsed->setText(tr("STR_SPACE_USED").arg(c->getSpaceUsed()));

	std::wostringstream ss3;
	ss3 << tr("STR_SOLDIERS_UC") << ">" << L'\x01'<< c->getNumSoldiers();
	_txtCrew->setText(ss3.str());

	_lstEquipment->setArrowColumn(203, ARROW_HORIZONTAL);
	_lstEquipment->setColumns(3, 156, 83, 41);
	_lstEquipment->setSelectable(true);
	_lstEquipment->setBackground(_window);
	_lstEquipment->setMargin(8);
	_lstEquipment->onLeftArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowPress);
	_lstEquipment->onLeftArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowRelease);
	_lstEquipment->onLeftArrowClick((ActionHandler)&CraftEquipmentState::lstEquipmentLeftArrowClick);
	_lstEquipment->onRightArrowPress((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowPress);
	_lstEquipment->onRightArrowRelease((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowRelease);
	_lstEquipment->onRightArrowClick((ActionHandler)&CraftEquipmentState::lstEquipmentRightArrowClick);
	_lstEquipment->onMousePress((ActionHandler)&CraftEquipmentState::lstEquipmentMousePress);

	int row = 0;
	const std::vector<std::string> &items = _game->getMod()->getItemsList();
	for (std::vector<std::string>::const_iterator i = items.begin(); i != items.end(); ++i)
	{
		RuleItem *rule = _game->getMod()->getItem(*i);
		int cQty = 0;
		if (rule->isFixed())
		{
			cQty = c->getVehicleCount(*i);
		}
		else
		{
			cQty = c->getItems()->getItem(*i);
			_totalItems += cQty;
		}
		if (rule->getBigSprite() > -1 && rule->getBattleType() != BT_NONE && rule->getBattleType() != BT_CORPSE &&
			_game->getSavedGame()->isResearched(rule->getRequirements()) &&
			(_base->getStorageItems()->getItem(*i) > 0 || cQty > 0))
		{
			_items.push_back(*i);
			std::wostringstream ss, ss2;
			if (_game->getSavedGame()->getMonthsPassed() > -1)
			{
				ss << _base->getStorageItems()->getItem(*i);
			}
			else
			{
				ss << "-";
			}
			ss2 << cQty;

			std::wstring s = tr(*i);
			if (rule->getBattleType() == BT_AMMO)
			{
				s.insert(0, L"  ");
			}
			_lstEquipment->addRow(3, s.c_str(), ss.str().c_str(), ss2.str().c_str());

			Uint8 color;
			if (cQty == 0)
			{
				if (rule->getBattleType() == BT_AMMO)
				{
					color = _ammoColor;
				}
				else
				{
					color = _lstEquipment->getColor();
				}
			}
			else
			{
					color = _lstEquipment->getSecondaryColor();
			}
			_lstEquipment->setRowColor(row, color);

			++row;
		}
	}

	_timerLeft = new Timer(250);
	_timerLeft->onTimer((StateHandler)&CraftEquipmentState::moveLeft);
	_timerRight = new Timer(250);
	_timerRight->onTimer((StateHandler)&CraftEquipmentState::moveRight);
}
Exemple #9
0
/**
 * This function is called when one of the mission's UFOs arrives at it's current destination.
 * It takes care of sending the UFO to the next waypoint, landing UFOs and
 * marking them for removal as required. It must set the game data in a way that the rest of the code
 * understands what to do.
 * @param ufo The UFO that reached it's waypoint.
 * @param engine The game engine, required to get access to game data and game rules.
 * @param globe The earth globe, required to get access to land checks.
 */
void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe)
{
	const Ruleset &rules = *engine.getRuleset();
	SavedGame &game = *engine.getSavedGame();
	const size_t curWaypoint = ufo.getTrajectoryPoint();
	const size_t nextWaypoint = curWaypoint + 1;
	const UfoTrajectory &trajectory = ufo.getTrajectory();
	int waveNumber = _nextWave - 1;
	if (waveNumber < 0)
	{
		waveNumber = _rule.getWaveCount() - 1;
	}

	const MissionWave &wave = _rule.getWave(waveNumber);
	if (nextWaypoint >= trajectory.getWaypointCount())
	{
		ufo.setDetected(false);
		ufo.setStatus(Ufo::DESTROYED);
		return;
	}
	ufo.setAltitude(trajectory.getAltitude(nextWaypoint));
	ufo.setTrajectoryPoint(nextWaypoint);
	const RuleRegion &regionRules = *rules.getRegion(_region);
	std::pair<double, double> pos = getWaypoint(trajectory, nextWaypoint, globe, regionRules);

	Waypoint *wp = new Waypoint();
	wp->setLongitude(pos.first);
	wp->setLatitude(pos.second);
	ufo.setDestination(wp);
	if (ufo.getAltitude() != "STR_GROUND")
	{
		if (ufo.getLandId() != 0)
		{
			ufo.setLandId(0);
		}
		// Set next waypoint.
		ufo.setSpeed((int)(ufo.getRules()->getMaxSpeed() * trajectory.getSpeedPercentage(nextWaypoint)));
	}
	else
	{
		// UFO landed.
		if (wave.objective && trajectory.getZone(curWaypoint) == (size_t)(_rule.getSpawnZone()))
		{
			// Remove UFO, replace with MissionSite.
			addScore(ufo.getLongitude(), ufo.getLatitude(), game);
			ufo.setStatus(Ufo::DESTROYED);

			MissionArea area = regionRules.getMissionPoint(trajectory.getZone(curWaypoint), &ufo);
			Texture *texture = rules.getGlobe()->getTexture(area.texture);
			AlienDeployment *deployment = rules.getDeployment(texture->getDeployment());
			
			MissionSite *missionSite = new MissionSite(&_rule, deployment);
			missionSite->setLongitude(ufo.getLongitude());
			missionSite->setLatitude(ufo.getLatitude());
			missionSite->setId(game.getId(deployment->getMarkerName()));
			missionSite->setSecondsRemaining(RNG::generate(deployment->getDurationMin(), deployment->getDurationMax()) * 3600);
			missionSite->setAlienRace(_race);
			missionSite->setTexture(area.texture);
			missionSite->setCity(area.name);
			game.getMissionSites()->push_back(missionSite);
			for (std::vector<Target*>::iterator t = ufo.getFollowers()->begin(); t != ufo.getFollowers()->end();)
			{
				Craft* c = dynamic_cast<Craft*>(*t);
				if (c && c->getNumSoldiers() != 0)
				{
					c->setDestination(missionSite);
					t = ufo.getFollowers()->begin();
				}
				else
				{
					++t;
				}
			}
		}
		else if (trajectory.getID() == "__RETALIATION_ASSAULT_RUN")
		{
			// Ignore what the trajectory might say, this is a base assault.
			// Remove UFO, replace with Base defense.
			ufo.setDetected(false);
			std::vector<Base *>::const_iterator found =
			    std::find_if (game.getBases()->begin(), game.getBases()->end(),
					 MatchBaseCoordinates(ufo.getLongitude(), ufo.getLatitude()));
			if (found == game.getBases()->end())
			{
				ufo.setStatus(Ufo::DESTROYED);
				// Only spawn mission if the base is still there.
				return;
			}
			ufo.setDestination(*found);
		}
		else
		{
			// Set timer for UFO on the ground.
			ufo.setSecondsRemaining(trajectory.groundTimer()*5);
			if (ufo.getDetected() && ufo.getLandId() == 0)
			{
				ufo.setLandId(engine.getSavedGame()->getId("STR_LANDING_SITE"));
			}
		}
	}
}
/**
 * The craft info can change
 * after going into other screens.
 */
void CraftInfoState::init()
{
	// Set palette
	_game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(3)), Palette::backPos, 16);

	Craft *c = _base->getCrafts()->at(_craft);

	_edtCraft->setText(c->getName(_game->getLanguage()));

	SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK");
	texture->getFrame(c->getRules()->getSprite() + 33)->setX(0);
	texture->getFrame(c->getRules()->getSprite() + 33)->setY(0);
	texture->getFrame(c->getRules()->getSprite() + 33)->blit(_sprite);

	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_DAMAGE_UC_") << L'\x01' << c->getDamagePercentage() << "%";
	_txtDamage->setText(ss.str());

	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_FUEL") << L'\x01' << c->getFuelPercentage() << "%";
	_txtFuel->setText(ss2.str());

	if (c->getRules()->getSoldiers() > 0)
	{
		_crew->clear();
		_equip->clear();

		Surface *frame1 = texture->getFrame(38);
		frame1->setY(0);
		for (int i = 0, x = 0; i < c->getNumSoldiers(); ++i, x += 10)
		{
			frame1->setX(x);
			frame1->blit(_crew);
		}

		Surface *frame2 = texture->getFrame(39);
		frame2->setY(0);
		int x = 0;
		for (int i = 0; i < c->getNumEquipment(); i += 4, x += 10)
		{
			frame2->setX(x);
			frame2->blit(_equip);
		}
		Surface *frame3 = texture->getFrame(40);
		for (int i = 0; i < c->getNumVehicles(); ++i, x += 10)
		{
			frame3->setX(x);
			frame3->blit(_equip);
		}
	}
	else
	{
		_crew->setVisible(false);
		_equip->setVisible(false);
		_btnCrew->setVisible(false);
		_btnEquip->setVisible(false);
		_btnArmor->setVisible(false);
	}

	if (c->getRules()->getWeapons() > 0)
	{
		CraftWeapon *w1 = c->getWeapons()->at(0);

		if (w1 != 0)
		{
			Surface *frame = texture->getFrame(w1->getRules()->getSprite() + 48);
			frame->setX(0);
			frame->setY(0);
			frame->blit(_weapon1);

			_txtW1Name->setText(_game->getLanguage()->getString(w1->getRules()->getType()));

			std::wstringstream ss3;
			ss3 << _game->getLanguage()->getString("STR_AMMO_") << L'\x01' << w1->getAmmo();
			_txtW1Ammo->setText(ss3.str());

			std::wstringstream ss4;
			ss4 << _game->getLanguage()->getString("STR_MAX") << L'\x01' << w1->getRules()->getAmmoMax();
			_txtW1Max->setText(ss4.str());
		}
		else
		{
			_weapon1->clear();
			_txtW1Name->setText(L"");
			_txtW1Ammo->setText(L"");
			_txtW1Max->setText(L"");
		}
	}
	else
	{
		_weapon1->setVisible(false);
		_btnW1->setVisible(false);
		_txtW1Name->setVisible(false);
		_txtW1Ammo->setVisible(false);
		_txtW1Max->setVisible(false);
	}

	if (c->getRules()->getWeapons() > 1)
	{
		CraftWeapon *w2 = c->getWeapons()->at(1);

		if (w2 != 0)
		{
			Surface *frame = texture->getFrame(w2->getRules()->getSprite() + 48);
			frame->setX(0);
			frame->setY(0);
			frame->blit(_weapon2);

			_txtW2Name->setText(_game->getLanguage()->getString(w2->getRules()->getType()));

			std::wstringstream ss5;
			ss5 << _game->getLanguage()->getString("STR_AMMO_") << L'\x01' << w2->getAmmo();
			_txtW2Ammo->setText(ss5.str());

			std::wstringstream ss6;
			ss6 << _game->getLanguage()->getString("STR_MAX") << L'\x01' << w2->getRules()->getAmmoMax();
			_txtW2Max->setText(ss6.str());
		}
		else
		{
			_weapon2->clear();
			_txtW2Name->setText(L"");
			_txtW2Ammo->setText(L"");
			_txtW2Max->setText(L"");
		}
	}
	else
	{
		_weapon2->setVisible(false);
		_btnW2->setVisible(false);
		_txtW2Name->setVisible(false);
		_txtW2Ammo->setVisible(false);
		_txtW2Max->setVisible(false);
	}
}
/**
 * Initializes all the elements in the Craft Soldiers screen.
 * @param game Pointer to the core game.
 * @param base Pointer to the base to get info from.
 * @param craft ID of the selected craft.
 */
CraftSoldiersState::CraftSoldiersState(Game *game, Base *base, unsigned int craft) : State(game), _base(base), _craft(craft)
{
	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton(288, 16, 16, 176);
	_txtTitle = new Text(300, 16, 16, 7);
	_txtName = new Text(114, 9, 16, 32);
	_txtRank = new Text(102, 9, 130, 32);
	_txtCraft = new Text(82, 9, 222, 32);
	_txtAvailable = new Text(110, 9, 16, 24);
	_txtUsed = new Text(110, 9, 130, 24);
	_lstSoldiers = new TextList(288, 128, 8, 40);

	// Set palette
	_game->setPalette(_game->getResourcePack()->getPalette("BACKPALS.DAT")->getColors(Palette::blockOffset(2)), Palette::backPos, 16);

	add(_window);
	add(_btnOk);
	add(_txtTitle);
	add(_txtName);
	add(_txtRank);
	add(_txtCraft);
	add(_txtAvailable);
	add(_txtUsed);
	add(_lstSoldiers);

	// Set up objects
	_window->setColor(Palette::blockOffset(15)+6);
	_window->setBackground(_game->getResourcePack()->getSurface("BACK02.SCR"));

	_btnOk->setColor(Palette::blockOffset(13)+10);
	_btnOk->setText(_game->getLanguage()->getString("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&CraftSoldiersState::btnOkClick);

	_txtTitle->setColor(Palette::blockOffset(15)+6);
	_txtTitle->setBig();
	Craft *c = _base->getCrafts()->at(_craft);
	std::wstring s;
	s = _game->getLanguage()->getString("STR_SELECT_SQUAD_FOR") + c->getName(_game->getLanguage());
	_txtTitle->setText(s);

	_txtName->setColor(Palette::blockOffset(15)+6);
	_txtName->setText(_game->getLanguage()->getString("STR_NAME_UC"));

	_txtRank->setColor(Palette::blockOffset(15)+6);
	_txtRank->setText(_game->getLanguage()->getString("STR_RANK"));

	_txtCraft->setColor(Palette::blockOffset(15)+6);
	_txtCraft->setText(_game->getLanguage()->getString("STR_CRAFT"));

	_txtAvailable->setColor(Palette::blockOffset(15)+6);
	_txtAvailable->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss;
	ss << _game->getLanguage()->getString("STR_SPACE_AVAILABLE") << L'\x01' << c->getRules()->getSoldiers() - c->getNumSoldiers();
	_txtAvailable->setText(ss.str());

	_txtUsed->setColor(Palette::blockOffset(15)+6);
	_txtUsed->setSecondaryColor(Palette::blockOffset(13));
	std::wstringstream ss2;
	ss2 << _game->getLanguage()->getString("STR_SPACE_USED") << L'\x01' << c->getNumSoldiers();
	_txtUsed->setText(ss2.str());

	_lstSoldiers->setColor(Palette::blockOffset(13)+10);
	_lstSoldiers->setArrowColor(Palette::blockOffset(15)+6);
	_lstSoldiers->setColumns(3, 114, 92, 74);
	_lstSoldiers->setSelectable(true);
	_lstSoldiers->setBackground(_window);
	_lstSoldiers->setMargin(8);
	_lstSoldiers->onMouseClick((ActionHandler)&CraftSoldiersState::lstSoldiersClick);

	int row = 0;
	for (std::vector<Soldier*>::iterator i = _base->getSoldiers()->begin(); i != _base->getSoldiers()->end(); ++i)
	{
		std::wstring s;
		if ((*i)->getCraft() == 0)
		{
			s = _game->getLanguage()->getString("STR_NONE_UC");
		}
		else
		{
			s = (*i)->getCraft()->getName(_game->getLanguage());
		}
		_lstSoldiers->addRow(3, (*i)->getName().c_str(), _game->getLanguage()->getString((*i)->getRankString()).c_str(), s.c_str());

		Uint8 color;
		if ((*i)->getCraft() == c)
		{
			color = Palette::blockOffset(13);
		}
		else if ((*i)->getCraft() != 0)
		{
			color = Palette::blockOffset(15)+6;
		}
		else
		{
			color = Palette::blockOffset(13)+10;
		}
		_lstSoldiers->setRowColor(row, color);
		row++;
	}
}