예제 #1
0
/**
 * Returns to the previous screen.
 * @param action Pointer to an action.
 */
void BaseDefenseState::btnOkClick(Action *)
{
	_timer->stop();
	_game->setPalette(_game->getResourcePack()->getPalette("PALETTES.DAT_0")->getColors());
	_game->popState();
	if(_ufo->getStatus() != Ufo::DESTROYED)
	{
		if (_base->getAvailableSoldiers(true) > 0)
		{
			size_t month = _game->getSavedGame()->getMonthsPassed();
			if (month > _game->getRuleset()->getAlienItemLevels().size()-1)
				month = _game->getRuleset()->getAlienItemLevels().size()-1;
			SavedBattleGame *bgame = new SavedBattleGame();
			_game->getSavedGame()->setBattleGame(bgame);
			bgame->setMissionType("STR_BASE_DEFENSE");
			BattlescapeGenerator bgen = BattlescapeGenerator(_game);
			bgen.setBase(_base);
			bgen.setAlienRace(_ufo->getAlienRace());
			bgen.setAlienItemlevel(_game->getRuleset()->getAlienItemLevels().at(month).at(RNG::generate(0,9)));
			bgen.run();
			_state->musicStop();
			_game->pushState(new BriefingState(_game, 0, _base));
		}
		else
		{
			_game->pushState(new BaseDestroyedState(_game, _base));
		}
	}
	// Whatever happens in the base defense, the UFO has finished its duty
	_ufo->setStatus(Ufo::DESTROYED);
}
예제 #2
0
/*
 * Animate explosion sprites. If their animation is finished remove them from the list.
 * If the list is empty, this states is finished.
 */
void ExplosionBState::think()
{
    for (std::set<Explosion*>::const_iterator i = _parent->getMap()->getExplosions()->begin(), inext = i; i != _parent->getMap()->getExplosions()->end(); i = inext)
    {
        ++inext;
        if(!(*i)->animate())
        {
            _parent->getMap()->getExplosions()->erase((*i));
            if (_parent->getMap()->getExplosions()->empty())
            {
                bool terrainExplosion = false;
                SavedBattleGame *save = _parent->getSave();
                // after the animation is done, the real explosion takes place
                if (_item)
                {
                    save->getTileEngine()->explode(_center, _item->getRules()->getPower(), _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
                }
                if (_tile)
                {
                    save->getTileEngine()->explode(_center, _tile->getExplosive(), DT_HE, 100, _unit);
                }
                if (!_tile && !_item)
                {
                    // explosion of a cyberdisc
                    save->getTileEngine()->explode(_center, 120, DT_HE, 8, _unit);
                    terrainExplosion = true;
                }

                // now check for new casualties
                _parent->checkForCasualties(_item, _unit, false, terrainExplosion);

                // if this explosion was caused by a unit shooting, now it's the time to put the gun down
                if (_unit && !_unit->isOut())
                {
                    _unit->aim(false);
                }
                _parent->getMap()->cacheUnits();
                _parent->popState();

                // check for terrain explosions
                Tile *t = save->getTileEngine()->checkForTerrainExplosions();
                if (t)
                {
                    Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
                    _parent->statePushNext(new ExplosionBState(_parent, p, 0, _unit, t));
                }

                return;
            }
        }
    }
}
예제 #3
0
/*
 * Animate explosion sprites. If their animation is finished remove them from the list.
 * If the list is empty, this states is finished.
 */
void ExplosionBState::think()
{
	for (std::set<Explosion*>::const_iterator i = _parent->getMap()->getExplosions()->begin(), inext = i; i != _parent->getMap()->getExplosions()->end(); i = inext)
	{
		++inext;
		if(!(*i)->animate())
		{
			_parent->getMap()->getExplosions()->erase((*i));
			if (_parent->getMap()->getExplosions()->empty())
			{
				SavedBattleGame *save = _parent->getGame()->getSavedGame()->getBattleGame();
				// after the animation is done, the real explosion takes place
				if (_item)
				{
					save->getTerrainModifier()->explode(_center, _item->getRules()->getPower(), _item->getRules()->getDamageType(), 100, _unit);
				}
				if (_tile)
				{
					save->getTerrainModifier()->explode(_center, _tile->getExplosive(), DT_HE, 100, _unit);
				}

				// now check for new casualties
				_parent->checkForCasualties(_item, _unit);

				// if this explosion was caused by a unit shooting, now it's the time to put the gun down and put the camera back on the shooter
				if (_unit && !_unit->isOut())
				{
					_unit->aim(false);
					if (_parent->getMap()->didCameraFollow())
					{
						_parent->getMap()->centerOnPosition(_unit->getPosition());
					}
				}
				_parent->getMap()->cacheUnits();
				_parent->popState();

				// check for terrain explosions
				Tile *t = save->getTerrainModifier()->checkForTerrainExplosions();
				if (t)
				{
					Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
					_parent->statePushNext(new ExplosionBState(_parent, p, 0, _unit, t));
				}

				return;
			}
		}
	}
}
예제 #4
0
/**
 * Returns to the previous screen.
 * @param action Pointer to an action.
 */
void ConfirmCydoniaState::btnYesClick(Action *)
{
	_game->popState();
	_game->popState();
	
	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	bgame->setMissionType("STR_MARS_CYDONIA_LANDING");
	BattlescapeGenerator bgen = BattlescapeGenerator(_game);
	bgen.setCraft(_craft);
	bgen.setAlienRace("STR_SECTOID");
	bgen.setWorldShade(15);
	bgen.run();

	_game->pushState(new BriefingState(_game, _craft));

}
예제 #5
0
/**
 * Enters the mission.
 * @param action Pointer to an action.
 */
void ConfirmLandingState::btnYesClick(Action *)
{
	_game->popState();
	_state->musicStop();
	Ufo* u = dynamic_cast<Ufo*>(_craft->getDestination());
	TerrorSite* t = dynamic_cast<TerrorSite*>(_craft->getDestination());
	AlienBase* b = dynamic_cast<AlienBase*>(_craft->getDestination());
	size_t month = _game->getSavedGame()->getMonthsPassed();
	if (month > _game->getRuleset()->getAlienItemLevels().size()-1)
		month = _game->getRuleset()->getAlienItemLevels().size()-1;

	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	BattlescapeGenerator bgen = BattlescapeGenerator(_game);
	bgen.setWorldTexture(_texture);
	bgen.setWorldShade(_shade);
	bgen.setCraft(_craft);
	if (u != 0)
	{
		if(u->getStatus() == Ufo::CRASHED)
			bgame->setMissionType("STR_UFO_CRASH_RECOVERY");
		else
			bgame->setMissionType("STR_UFO_GROUND_ASSAULT");
		bgen.setUfo(u);
		bgen.setAlienRace(u->getAlienRace());
	}
	else if (t != 0)
	{
		bgame->setMissionType("STR_TERROR_MISSION");
		bgen.setTerrorSite(t);
		bgen.setAlienRace(t->getAlienRace());
	}
	else if (b != 0)
	{
		bgame->setMissionType("STR_ALIEN_BASE_ASSAULT");
		bgen.setAlienBase(b);
		bgen.setAlienRace(b->getAlienRace());
	}
	else
	{
		throw Exception("No mission available!");
	}
	bgen.setAlienItemlevel(_game->getRuleset()->getAlienItemLevels().at(month).at(RNG::generate(0,9)));
	bgen.run();
	_game->pushState(new BriefingState(_game, _craft));
}
예제 #6
0
/**
 * Enters the mission.
 * @param action Pointer to an action.
 */
void ConfirmLandingState::btnYesClick(Action *action)
{
	_game->popState();
	Ufo* u = dynamic_cast<Ufo*>(_craft->getDestination());
	TerrorSite* t = dynamic_cast<TerrorSite*>(_craft->getDestination());
	AlienBase* b = dynamic_cast<AlienBase*>(_craft->getDestination());
	if (u != 0)
	{
		SavedBattleGame *bgame = new SavedBattleGame();
		_game->getSavedGame()->setBattleGame(bgame);
		if(u->getStatus() == Ufo::CRASHED)
			bgame->setMissionType("STR_UFO_CRASH_RECOVERY");
		else
			bgame->setMissionType("STR_UFO_GROUND_ASSAULT");
		BattlescapeGenerator bgen = BattlescapeGenerator(_game);
		bgen.setWorldTexture(_texture);
		bgen.setWorldShade(_shade);
		bgen.setCraft(_craft);
		bgen.setUfo(u);
		bgen.setAlienRace(u->getAlienRace());
		bgen.setAlienItemlevel(0);
		bgen.run();

		_game->pushState(new BriefingState(_game, _craft));
	}
	else if (t != 0)
	{
		SavedBattleGame *bgame = new SavedBattleGame();
		_game->getSavedGame()->setBattleGame(bgame);
		bgame->setMissionType("STR_TERROR_MISSION");
		BattlescapeGenerator bgen = BattlescapeGenerator(_game);
		bgen.setWorldTexture(_texture);
		bgen.setWorldShade(_shade);
		bgen.setCraft(_craft);
		bgen.setTerrorSite(t);
		bgen.setAlienRace(t->getAlienRace());
		bgen.setAlienItemlevel(0);
		bgen.run();

		_game->pushState(new BriefingState(_game, _craft));
	}
	else if (b != 0)
	{
		SavedBattleGame *bgame = new SavedBattleGame();
		_game->getSavedGame()->setBattleGame(bgame);
		bgame->setMissionType("STR_ALIEN_BASE_ASSAULT");
		BattlescapeGenerator bgen = BattlescapeGenerator(_game);
		bgen.setWorldTexture(_texture);
		bgen.setWorldShade(_shade);
		bgen.setCraft(_craft);
		bgen.setAlienBase(b);
		bgen.setAlienRace(b->getAlienRace());
		bgen.setAlienItemlevel(0);
		bgen.run();

		_game->pushState(new BriefingState(_game, _craft));
	}
}
예제 #7
0
/**
 * Enters the mission.
 * @param action Pointer to an action.
 */
void ConfirmLandingState::btnYesClick(Action *)
{
	_game->popState();
	Ufo* u = dynamic_cast<Ufo*>(_craft->getDestination());
	MissionSite* m = dynamic_cast<MissionSite*>(_craft->getDestination());
	AlienBase* b = dynamic_cast<AlienBase*>(_craft->getDestination());

	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	BattlescapeGenerator bgen(_game);
	bgen.setWorldTexture(_texture);
	bgen.setWorldShade(_shade);
	bgen.setCraft(_craft);
	if (u != 0)
	{
		if (u->getStatus() == Ufo::CRASHED)
			bgame->setMissionType("STR_UFO_CRASH_RECOVERY");
		else
			bgame->setMissionType("STR_UFO_GROUND_ASSAULT");
		bgen.setUfo(u);
		bgen.setAlienRace(u->getAlienRace());
	}
	else if (m != 0)
	{
		bgame->setMissionType(m->getDeployment()->getType());
		bgen.setMissionSite(m);
		bgen.setAlienRace(m->getAlienRace());
	}
	else if (b != 0)
	{
		bgame->setMissionType(b->getDeployment()->getType());
		bgen.setAlienBase(b);
		bgen.setAlienRace(b->getAlienRace());
		bgen.setWorldTexture(0);
	}
	else
	{
		throw Exception("No mission available!");
	}
	bgen.run();
	_game->pushState(new BriefingState(_craft));
}
예제 #8
0
/**
 * Returns to the previous screen.
 * @param action Pointer to an action.
 */
void ConfirmCydoniaState::btnYesClick(Action *)
{
	_game->popState();
	_game->popState();
	
	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	BattlescapeGenerator bgen = BattlescapeGenerator(_game);
	for (std::vector<std::string>::const_iterator i = _game->getRuleset()->getDeploymentsList().begin(); i != _game->getRuleset()->getDeploymentsList().end(); ++i)
	{
		AlienDeployment *deployment = _game->getRuleset()->getDeployment(*i);
		if (deployment->isFinalDestination())
		{
			bgame->setMissionType(*i);
			bgen.setAlienRace(deployment->getRace());
			break;
		}
	}
	bgen.setCraft(_craft);
	bgen.run();

	_game->pushState(new BriefingState(_craft));

}
예제 #9
0
void ExplosionBState::explode()
{
    bool terrainExplosion = false;
    SavedBattleGame *save = _parent->getSave();
    // after the animation is done, the real explosion/hit takes place
    if (_item)
    {
        if (_areaOfEffect)
        {
            save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
        }
        else
        {
            BattleUnit *victim = save->getTileEngine()->hit(_center, _power, _item->getRules()->getDamageType(), _unit);
            // check if this unit turns others into zombies
            if (!_unit->getZombieUnit().empty() && victim)
            {
                // converts the victim to a zombie
                _parent->convertUnit(victim, _unit->getZombieUnit());
            }
        }
    }
    if (_tile)
    {
        save->getTileEngine()->explode(_center, _power, DT_HE, 100);
    }
    if (!_tile && !_item)
    {
        // explosion not caused by terrain or an item, must be by a unit (cyberdisc)
        save->getTileEngine()->explode(_center, _power, DT_HE, 8);
        terrainExplosion = true;
    }

    // now check for new casualties
    _parent->checkForCasualties(_item, _unit, false, terrainExplosion);

    // if this explosion was caused by a unit shooting, now it's the time to put the gun down
    if (_unit && !_unit->isOut())
    {
        _unit->aim(false);
    }
    _parent->getMap()->cacheUnits();
    _parent->popState();

    // check for terrain explosions
    Tile *t = save->getTileEngine()->checkForTerrainExplosions();
    if (t)
    {
        Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
        _parent->statePushNext(new ExplosionBState(_parent, p, 0, _unit, t));
    }

}
예제 #10
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}

		BattleUnit *victim = 0;

		if (_areaOfEffect)
		{
			save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
		}
		else if (!_cosmetic)
		{
			ItemDamageType type = _item->getRules()->getDamageType();

			victim = save->getTileEngine()->hit(_center, _power, type, _unit);
		}
		// check if this unit turns others into zombies
		if (!_item->getRules()->getZombieUnit().empty()
			&& victim
			&& victim->getArmor()->getSize() == 1
			&& (victim->getGeoscapeSoldier() || victim->getUnitRules()->getRace() == "STR_CIVILIAN")
			&& victim->getSpawnUnit().empty())
		{
			// converts the victim to a zombie on death
			victim->setRespawn(true);
			victim->setSpawnUnit(_item->getRules()->getZombieUnit());
		}
	}
	if (_tile)
	{
		ItemDamageType DT;
		switch (_tile->getExplosiveType())
		{
		case 0:
			DT = DT_HE;
			break;
		case 5:
			DT = DT_IN;
			break;
		case 6:
			DT = DT_STUN;
			break;
		default:
			DT = DT_SMOKE;
			break;
		}
		if (DT != DT_HE)
		{
			_tile->setExplosive(0,0,true);
		}
		save->getTileEngine()->explode(_center, _power, DT, _power/10);
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		int radius = 6;
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
		{
			radius = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape())->getExplosionRadius();
		}
		save->getTileEngine()->explode(_center, _power, DT_HE, radius);
		terrainExplosion = true;
	}

	if (!_cosmetic)
	{
		// now check for new casualties
		_parent->checkForCasualties(_item, _unit, false, terrainExplosion);
	}

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
		_unit->setCache(0);
	}
	_parent->getMap()->cacheUnits();
	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, 0, _unit, t));
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		for (std::vector<BattleItem*>::iterator j = _parent->getSave()->getItems()->begin(); j != _parent->getSave()->getItems()->end(); ++j)
		{
			if (_item->getId() == (*j)->getId())
			{
				_parent->getSave()->removeItem(_item);
				break;
			}
		}
	}
}
예제 #11
0
/**
 * Prepares debriefing: gathers Aliens, Corpses, Artefacts, UFO Components.
 * Adds the items to the craft.
 * Also calculates the soldiers experience, and possible promotions.
 * If aborted, only the things on the exit area are recovered.
 */
void DebriefingState::prepareDebriefing()
{
	_stats.push_back(new DebriefingStat("STR_ALIENS_KILLED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_CORPSES_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_LIVE_ALIENS_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ARTIFACTS_RECOVERED", false));
	_stats.push_back(new DebriefingStat("STR_ALIEN_BASE_CONTROL_DESTROYED", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_KILLED_BY_ALIENS", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_KILLED_BY_XCOM_OPERATIVES", false));
	_stats.push_back(new DebriefingStat("STR_CIVILIANS_SAVED", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_KILLED", false));
	//_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_RETIRED_THROUGH_INJURY", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_OPERATIVES_MISSING_IN_ACTION", false));
	_stats.push_back(new DebriefingStat("STR_TANKS_DESTROYED", false));
	_stats.push_back(new DebriefingStat("STR_XCOM_CRAFT_LOST", false));
	_stats.push_back(new DebriefingStat("STR_UFO_POWER_SOURCE", true));
	_stats.push_back(new DebriefingStat("STR_UFO_NAVIGATION", true));
	_stats.push_back(new DebriefingStat("STR_UFO_CONSTRUCTION", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_FOOD", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_REPRODUCTION", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ENTERTAINMENT", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_SURGERY", true));
	_stats.push_back(new DebriefingStat("STR_EXAMINATION_ROOM", true));
	_stats.push_back(new DebriefingStat("STR_ALIEN_ALLOYS", true));
	_stats.push_back(new DebriefingStat("STR_ELERIUM_115", true));

	SavedGame *save = _game->getSavedGame();
	SavedBattleGame *battle = save->getBattleGame();
	bool aborted = battle->isAborted();
	Craft* craft = 0;
	std::vector<Craft*>::iterator craftIterator;
	Base* base = 0;

	int playerInExitArea = 0; // if this stays 0 the craft is lost...
	int playersSurvived = 0; // if this stays 0 the craft is lost...

	for (std::vector<Base*>::iterator i = save->getBases()->begin(); i != save->getBases()->end(); ++i)
	{

		// in case we have a craft - check which craft it is about
		for (std::vector<Craft*>::iterator j = (*i)->getCrafts()->begin(); j != (*i)->getCrafts()->end(); ++j)
		{
			if ((*j)->isInBattlescape())
			{
				craft = (*j);
				base = (*i);
				craftIterator = j;
				craft->returnToBase();
				craft->setLowFuel(true);
				craft->setInBattlescape(false);
			}
		}
	}

	// UFO crash/landing site disappears
	for (std::vector<Ufo*>::iterator i = save->getUfos()->begin(); i != save->getUfos()->end(); ++i)
	{
		if ((*i)->isInBattlescape())
		{
			delete *i;
			save->getUfos()->erase(i);
			break;
		}
	}

	// lets see what happens with units
	for (std::vector<BattleUnit*>::iterator j = battle->getUnits()->begin(); j != battle->getUnits()->end(); ++j)
	{
		UnitStatus status = (*j)->getStatus();
		UnitFaction faction = (*j)->getFaction();
		int value = (*j)->getValue();
		Soldier *soldier = save->getSoldier((*j)->getId());

		if (status == STATUS_DEAD)
		{
			if (faction == FACTION_HOSTILE)
			{
				addStat("STR_ALIENS_KILLED", 1, value);
			}
			if (faction == FACTION_PLAYER)
			{
				if (soldier != 0)
				{
					addStat("STR_XCOM_OPERATIVES_KILLED", 1, -value);
					for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end(); ++i)
					{
						if ((*i) == soldier)
						{
							delete (*i);
							base->getSoldiers()->erase(i);
							break;
						}
					}
				}
				else
				{
					// non soldier player = tank
					addStat("STR_TANKS_DESTROYED", 1, -value);
				}
			}
		}
		else if (status == STATUS_UNCONSCIOUS)
		{
			if (faction == FACTION_HOSTILE && (!aborted || (*j)->isInExitArea()))
			{
				addStat("STR_LIVE_ALIENS_RECOVERED", 1, value);
			}
		}
		else if (faction == FACTION_PLAYER)
		{
			playersSurvived++;
			if ((*j)->isInExitArea() || !aborted)
			{
				playerInExitArea++;
				(*j)->postMissionProcedures(save);
			}
			else
			{
				addStat("STR_XCOM_OPERATIVES_MISSING_IN_ACTION", 1, -value);
				for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end(); ++i)
				{
					if ((*i) == soldier)
					{
						delete (*i);
						base->getSoldiers()->erase(i);
						break;
					}
				}
			}
		}
	}
	if (((playerInExitArea == 0 && aborted) || (playersSurvived == 0)) && craft != 0)
	{
		addStat("STR_XCOM_CRAFT_LOST", 1, -200);
		delete craft;
		base->getCrafts()->erase(craftIterator);
		for (std::vector<Soldier*>::iterator i = base->getSoldiers()->begin(); i != base->getSoldiers()->end();)
		{
			if ((*i)->getCraft() == craft)
			{
				delete (*i);
				i = base->getSoldiers()->erase(i);
			}
			else
			{
				 ++i;
			}
		}
		_txtTitle->setText(_game->getLanguage()->getString("STR_CRAFT_IS_LOST"));
		return;
	}

	if (!aborted && playersSurvived > 0) 	// RECOVER UFO : run through all tiles to recover UFO components and items
	{
		if (battle->getMissionType() == "STR_BASE_DEFENCE")
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_BASE_IS_SAVED"));
		}
		else
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_UFO_IS_RECOVERED"));
		}

		for (int i = 0; i < battle->getHeight() * battle->getLength() * battle->getWidth(); ++i)
		{
			for (int part = 0; part < 4; part++)
			{
				if (battle->getTiles()[i]->getMapData(part))
				{
					switch (battle->getTiles()[i]->getMapData(part)->getSpecialType())
					{
					case UFO_POWER_SOURCE:
						addStat("STR_UFO_POWER_SOURCE", 1, 1); break;
					case DESTROY_OBJECTIVE:break; // this is the brain
					case UFO_NAVIGATION:
						addStat("STR_UFO_NAVIGATION", 1, 1); break;
					case ALIEN_FOOD:
						addStat("STR_ALIEN_FOOD", 1, 1); break;
					case ALIEN_REPRODUCTION:
						addStat("STR_ALIEN_REPRODUCTION", 1, 1); break;
					case ALIEN_ENTERTAINMENT:
						addStat("STR_ALIEN_ENTERTAINMENT", 1, 1); break;
					case ALIEN_SURGERY:
						addStat("STR_ALIEN_SURGERY", 1, 1); break;
					case UNKNOWN09:
						addStat("STR_UFO_CONSTRUCTION", 1, 1); break;
					case ALIEN_ALLOYS:
						addStat("STR_ALIEN_ALLOYS", 1, 1); break;
					case EXAM_ROOM:
						addStat("STR_EXAMINATION_ROOM", 1, 1); break;
					}

				}
			}
		}

		// alien alloys recovery values are divided by 10 or divided by 150 in case of an alien base
		int divider = battle->getMissionType()=="STR_ALIEN_BASE_ASSAULT"?150:10;
		for (std::vector<DebriefingStat*>::iterator i = _stats.begin(); i != _stats.end(); ++i)
		{
			if ((*i)->item == "STR_ALIEN_ALLOYS")
			{
				(*i)->qty = (*i)->qty / divider;
				(*i)->score = (*i)->score / divider;
				break;
			}

			/*if ((*i)->recovery && (*i)->qty > 0)
			{
				base->getItems()->addItem((*i)->item, (*i)->qty);
			}*/
		}
	}
	else
	{
		if (battle->getMissionType() == "STR_BASE_DEFENCE")
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_BASE_IS_LOST"));
		}
		else
		{
			_txtTitle->setText(_game->getLanguage()->getString("STR_UFO_IS_NOT_RECOVERED"));
		}
	}

}
예제 #12
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}

		if (_areaOfEffect)
		{
			save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
		}
		else
		{
			BattleUnit *victim = save->getTileEngine()->hit(_center, _power, _item->getRules()->getDamageType(), _unit);
			// check if this unit turns others into zombies
			if (!_unit->getZombieUnit().empty()
				&& victim
				&& victim->getArmor()->getSize() == 1
				&& victim->getSpawnUnit().empty()
				&& victim->getOriginalFaction() != FACTION_HOSTILE)
			{
				// converts the victim to a zombie on death
				victim->setSpecialAbility(SPECAB_RESPAWN);
				victim->setSpawnUnit(_unit->getZombieUnit());
			}
		}
	}
	if (_tile)
	{
		save->getTileEngine()->explode(_center, _power, DT_HE, _power/10);
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		save->getTileEngine()->explode(_center, _power, DT_HE, 6);
		terrainExplosion = true;
	}

	// now check for new casualties
	_parent->checkForCasualties(_item, _unit, false, terrainExplosion);

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
	}
	_parent->getMap()->cacheUnits();
	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
		_parent->statePushFront(new ExplosionBState(_parent, p, 0, _unit, t));
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		for (std::vector<BattleItem*>::iterator j = _parent->getSave()->getItems()->begin(); j != _parent->getSave()->getItems()->end(); ++j)
		{
			if (_item->getId() == (*j)->getId())
			{
				delete *j;
				_parent->getSave()->getItems()->erase(j);
				break;
			}
		}
	}
}
예제 #13
0
/**
 * Starts the battle.
 * @param action Pointer to an action.
 */
void NewBattleState::btnOkClick(Action *)
{
	save();
	if (_missionTypes[_cbxMission->getSelected()] != "STR_BASE_DEFENSE" && _craft->getNumSoldiers() == 0 && _craft->getNumVehicles() == 0)
	{
		return;
	}

	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	bgame->setMissionType(_missionTypes[_cbxMission->getSelected()]);
	BattlescapeGenerator bgen = BattlescapeGenerator(_game);
	Base *base = 0;

	bgen.setTerrain(_game->getMod()->getTerrain(_terrainTypes[_cbxTerrain->getSelected()]));

	// base defense
	if (_missionTypes[_cbxMission->getSelected()] == "STR_BASE_DEFENSE")
	{
		base = _craft->getBase();
		bgen.setBase(base);
		_craft = 0;
	}
	// alien base
	else if (_game->getMod()->getDeployment(bgame->getMissionType())->isAlienBase())
	{
		AlienBase *b = new AlienBase(_game->getMod()->getDeployment(bgame->getMissionType()));
		b->setId(1);
		b->setAlienRace(_alienRaces[_cbxAlienRace->getSelected()]);
		_craft->setDestination(b);
		bgen.setAlienBase(b);
		_game->getSavedGame()->getAlienBases()->push_back(b);
	}
	// ufo assault
	else if (_craft && _game->getMod()->getUfo(_missionTypes[_cbxMission->getSelected()]))
	{
		Ufo *u = new Ufo(_game->getMod()->getUfo(_missionTypes[_cbxMission->getSelected()]));
		u->setId(1);
		_craft->setDestination(u);
		bgen.setUfo(u);
		// either ground assault or ufo crash
		if (RNG::generate(0,1) == 1)
		{
			u->setStatus(Ufo::LANDED);
			bgame->setMissionType("STR_UFO_GROUND_ASSAULT");
		}
		else
		{
			u->setStatus(Ufo::CRASHED);
			bgame->setMissionType("STR_UFO_CRASH_RECOVERY");
		}
		_game->getSavedGame()->getUfos()->push_back(u);
	}
	// mission site
	else
	{
		const AlienDeployment *deployment = _game->getMod()->getDeployment(bgame->getMissionType());
		const RuleAlienMission *mission = _game->getMod()->getAlienMission(_game->getMod()->getAlienMissionList().front()); // doesn't matter
		MissionSite *m = new MissionSite(mission, deployment);
		m->setId(1);
		m->setAlienRace(_alienRaces[_cbxAlienRace->getSelected()]);
		_craft->setDestination(m);
		bgen.setMissionSite(m);
		_game->getSavedGame()->getMissionSites()->push_back(m);
	}

	if (_craft)
	{
		_craft->setSpeed(0);
		bgen.setCraft(_craft);
	}

	_game->getSavedGame()->setDifficulty((GameDifficulty)_cbxDifficulty->getSelected());

	bgen.setWorldShade(_slrDarkness->getValue());
	bgen.setAlienRace(_alienRaces[_cbxAlienRace->getSelected()]);
	bgen.setAlienItemlevel(_slrAlienTech->getValue());
	bgame->setDepth(_slrDepth->getValue());

	bgen.run();

	_game->popState();
	_game->popState();
	_game->pushState(new BriefingState(_craft, base));
	_craft = 0;
}
예제 #14
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// last minute adjustment: determine if we actually
	if (_hit)
	{
		if (_unit && !_unit->isOut())
		{
			_unit->aim(false);
		}

		if (_power <= 0)
		{
			_parent->popState();
			return;
		}

		int sound = _item->getRules()->getMeleeHitSound();
		if (!_pistolWhip)
		{
			// melee weapon with ammo
			BattleItem *ammo = _item->getAmmoItem();
			if (ammo)
			{
				optValue(sound, ammo->getRules()->getMeleeHitSound());
			}
		}
		_parent->playSound(sound, _action.target);
	}
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}
	}

	bool range = !(_hit || (_item && _item->getRules()->getBattleType() == BT_PSIAMP));

	if (_areaOfEffect)
	{
		save->getTileEngine()->explode(_center, _power, _damageType, _radius, _unit, _item, range);
	}
	else
	{
		BattleUnit *victim = save->getTileEngine()->hit(_center, _power, _damageType, _unit, _item, range);
		// check if this unit turns others into zombies
		if (!_item->getRules()->getZombieUnit().empty()
			&& RNG::percent(_item->getRules()->getSpecialChance())
			&& victim
			&& victim->getArmor()->getZombiImmune() == false
			&& victim->getSpawnUnit().empty()
			&& victim->getOriginalFaction() != FACTION_HOSTILE)
		{
			// converts the victim to a zombie on death
			victim->setRespawn(true);
			victim->setSpawnUnit(_item->getRules()->getZombieUnit());
		}
	}

	if (_tile)
	{
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		terrainExplosion = true;
	}

	// now check for new casualties
	_parent->checkForCasualties(_item ? _damageType : 0, _item, _unit, false, terrainExplosion);
	// revive units if damage could give hp or reduce stun
	_parent->getSave()->reviveUnconsciousUnits(true);

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		_parent->getSave()->removeItem(_item);
	}

	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = t->getPosition().toVexel();
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, BA_NONE, 0, _unit, t));
	}
}
예제 #15
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// last minute adjustment: determine if we actually 
	if (_hit)
	{
		save->getBattleGame()->getCurrentAction()->type = BA_NONE;
		BattleUnit *targetUnit = save->getTile(_center / Position(16, 16, 24))->getUnit();
		if (_unit && !_unit->isOut())
		{
			_unit->aim(false);
			_unit->setCache(0);
		}
		if (!RNG::percent(_unit->getFiringAccuracy(BA_HIT, _item)))
		{
			_parent->getMap()->cacheUnits();
			_parent->popState();
			return;
		}
		else if (targetUnit && targetUnit->getOriginalFaction() == FACTION_HOSTILE &&
				_unit->getOriginalFaction() == FACTION_PLAYER)
		{
			_unit->addMeleeExp();
		}
		if (_item->getRules()->getMeleeHitSound() != -1)
		{
			_parent->getResourcePack()->getSoundByDepth(_parent->getDepth(), _item->getRules()->getMeleeHitSound())->play();
		}
	}
	// after the animation is done, the real explosion/hit takes place
	if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}

		if (_areaOfEffect)
		{
			save->getTileEngine()->explode(_center, _power, _item->getRules()->getDamageType(), _item->getRules()->getExplosionRadius(), _unit);
		}
		else
		{
			ItemDamageType type = _item->getRules()->getDamageType();
			if (_pistolWhip)
			{
				type = DT_STUN;
			}
			BattleUnit *victim = save->getTileEngine()->hit(_center, _power, type, _unit);
			// check if this unit turns others into zombies
			if (!_item->getRules()->getZombieUnit().empty()
				&& victim
				&& victim->getArmor()->getSize() == 1
				&& victim->getSpawnUnit().empty()
				&& victim->getOriginalFaction() != FACTION_HOSTILE)
			{
				// converts the victim to a zombie on death
				victim->setSpecialAbility(SPECAB_RESPAWN);
				victim->setSpawnUnit(_item->getRules()->getZombieUnit());
			}
		}
	}
	if (_tile)
	{
		save->getTileEngine()->explode(_center, _power, DT_HE, _power/10);
		terrainExplosion = true;
	}
	if (!_tile && !_item)
	{
		int radius = 6;
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		if (_unit && _unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH)
		{
			radius = _parent->getRuleset()->getItem(_unit->getArmor()->getCorpseGeoscape())->getExplosionRadius();
		}
		save->getTileEngine()->explode(_center, _power, DT_HE, radius);
		terrainExplosion = true;
	}

	// now check for new casualties
	_parent->checkForCasualties(_item, _unit, false, terrainExplosion);

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_unit && !_unit->isOut() && _lowerWeapon)
	{
		_unit->aim(false);
		_unit->setCache(0);
	}
	_parent->getMap()->cacheUnits();
	_parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24);
		p += Position(8,8,0);
		_parent->statePushFront(new ExplosionBState(_parent, p, 0, _unit, t));
	}

	if (_item && (_item->getRules()->getBattleType() == BT_GRENADE || _item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		for (std::vector<BattleItem*>::iterator j = _parent->getSave()->getItems()->begin(); j != _parent->getSave()->getItems()->end(); ++j)
		{
			if (_item->getId() == (*j)->getId())
			{
				delete *j;
				_parent->getSave()->getItems()->erase(j);
				break;
			}
		}
	}
}
예제 #16
0
/**
 * Calculates the effects of the explosion.
 */
void ExplosionBState::explode()
{
	bool terrainExplosion = false;
	SavedBattleGame *save = _parent->getSave();
	// last minute adjustment: determine if we actually
	if (_hit)
	{
		if (_attack.attacker && !_attack.attacker->isOut())
		{
			_attack.attacker->aim(false);
		}

		if (_power <= 0)
		{
			_parent->popState();
			return;
		}

		int sound = _attack.weapon_item->getRules()->getMeleeHitSound();
		if (_attack.weapon_item != _attack.damage_item)
		{
			// melee weapon with ammo
			optValue(sound, _attack.damage_item->getRules()->getMeleeHitSound());
		}
		_parent->playSound(sound, _center.toTile());
	}

	bool range = !(_hit || (_attack.weapon_item && _attack.weapon_item->getRules()->getBattleType() == BT_PSIAMP));

	// after the animation is done, the real explosion/hit takes place
	/*if (_item)
	{
		if (!_unit && _item->getPreviousOwner())
		{
			_unit = _item->getPreviousOwner();
		}*/

	if (_areaOfEffect)
	{
		save->getTileEngine()->explode(_attack, _center, _power, _damageType, _radius, range);
	}
	else //if (!_cosmetic)
	{

		if (_damageType->ResistType == DT_TELEPORT)
		{
			Tile *destination = _tile ? _tile : save->getTile(Position(_center.x / 16, _center.y / 16, _center.z / 24));
			if (_attack.attacker && destination && !destination->getUnit())
			{
				save->getTile(_attack.attacker->getPosition())->setUnit(0);
				const Position& oldPosition = _attack.attacker->getPosition();
				_attack.attacker->setPosition(destination->getPosition());
				destination->setUnit(_attack.attacker);
				save->getTileEngine()->calculateFOV(oldPosition);
				save->getTileEngine()->calculateFOV(destination->getPosition());
			}
		}
		else
		{
			BattleUnit *victim = save->getTileEngine()->hit(_attack, _center, _power, _action.type, _damageType, range);

			const RuleItem *hitItem = _attack.damage_item->getRules();

			// check if this unit turns others into zombies
			if (!hitItem->getZombieUnit().empty()
				&& RNG::percent(hitItem->getSpecialChance())
				&& victim
				&& victim->getArmor()->getZombiImmune() == false
				&& victim->getSpawnUnit().empty()
				&& victim->getOriginalFaction() != FACTION_HOSTILE)
			{
				// converts the victim to a zombie on death
				victim->setRespawn(true);
				victim->setSpawnUnit(hitItem->getZombieUnit());
			}
		}
	}
	//}

	if (_tile)
	{
		/*ItemDamageType DT;
		switch (_tile->getExplosiveType())
		{
		case 0:
			DT = DT_HE;
			break;
		case 5:
			DT = DT_IN;
			break;
		case 6:
			DT = DT_STUN;
			break;
		default:
			DT = DT_SMOKE;
			break;
		}
		if (DT != DT_HE)
		{
			_tile->setExplosive(0, 0, true);
		}
		save->getTileEngine()->explode(_center, _power, _parent->getCurrentAction()->type, DT, _power / 10, 0);*/
		terrainExplosion = true;
	}
	if (!_tile && !_attack.damage_item)
	{
		/*int radius = 6;
		// explosion not caused by terrain or an item, must be by a unit (cyberdisc)
		if (_unit && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE))
		{
			radius = _parent->getMod()->getItem(_unit->getArmor()->getCorpseGeoscape(), true)->getExplosionRadius();
		}
		save->getTileEngine()->explode(_center, _power, _parent->getCurrentAction()->type, DT_HE, radius, 0);*/
		terrainExplosion = true;
	}

	// now check for new casualties
	_parent->checkForCasualties(_damageType, _attack, false, terrainExplosion, _subState);
	// revive units if damage could give hp or reduce stun
	_parent->getSave()->reviveUnconsciousUnits(true);

	// if this explosion was caused by a unit shooting, now it's the time to put the gun down
	if (_attack.attacker && !_attack.attacker->isOut() && _lowerWeapon)
	{
		_attack.attacker->aim(false);
	}

	if (_attack.damage_item && (_attack.damage_item->getRules()->getBattleType() == BT_GRENADE || _attack.damage_item->getRules()->getBattleType() == BT_PROXIMITYGRENADE))
	{
		_parent->getSave()->removeItem(_attack.damage_item);
	}
	//_finished = true;
	//if(!_subState) _parent->popState();

	// check for terrain explosions
	Tile *t = save->getTileEngine()->checkForTerrainExplosions();
	if (t)
	{
		Position p = t->getPosition().toVexel();
		p += Position(8, 8, 0);
		{
			//_parent->statePushFront(new ExplosionBState(_parent, p, BattleActionAttack{ BA_NONE, _attack.attacker, }, t));
			if (!_subState)
			{
				_parent->statePushFront(new ExplosionBState(_parent, p, BattleActionAttack{ BA_NONE, _attack.attacker, }, t));
			}
			else
			{
				_terrainExplosion = new ExplosionBState(_parent, p, BattleActionAttack{ BA_NONE, _attack.attacker, }, t, false, false, true);
			}
		}
	}
}