/** * Sets up an UnitDieBState. */ UnitDieBState::UnitDieBState(BattlescapeGame *parent, BattleUnit *unit, ItemDamageType damageType, bool noSound) : BattleState(parent), _unit(unit), _damageType(damageType), _noSound(noSound) { // don't show the "fall to death" animation when a unit is blasted with explosives or he is already unconscious if (_damageType == DT_HE || _unit->getStatus() == STATUS_UNCONSCIOUS) { _unit->startFalling(); if (!_noSound) { playDeathSound(); } while (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } } else { if (_unit->getFaction() == FACTION_PLAYER) _parent->getMap()->setUnitDying(true); _parent->getMap()->getCamera()->centerOnPosition(_unit->getPosition()); _parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED); _originalDir = _unit->getDirection(); _unit->lookAt(3); // unit goes into status TURNING to prepare for a nice dead animation } _unit->clearVisibleTiles(); _unit->clearVisibleUnits(); parent->resetSituationForAI(); if (_unit->getFaction() == FACTION_HOSTILE) { std::vector<Node *> *nodes = parent->getSave()->getNodes(); if (!nodes) return; // this better not happen. for (std::vector<Node*>::iterator n = nodes->begin(); n != nodes->end(); ++n) { if (parent->getSave()->getTileEngine()->distanceSq((*n)->getPosition(), unit->getPosition()) < 4) { (*n)->setType((*n)->getType() | Node::TYPE_DANGEROUS); } } } }
/** * Runs state functionality every cycle. * Progresses the death, displays any messages, checks if the mission is over, ... */ void UnitDieBState::think() { if (_unit->getDirection() != 3 && _damageType != DT_HE) { int dir = _unit->getDirection() + 1; if (dir == 8) { dir = 0; } _unit->lookAt(dir); _unit->turn(); if (dir == 3) { _parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED); } } else if (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } else if (!_unit->isOut()) { _unit->startFalling(); if (!_noSound) { playDeathSound(); } if (_unit->getRespawn()) { while (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } } } if (_unit->isOut()) { if (!_noSound && _damageType == DT_HE && _unit->getStatus() != STATUS_UNCONSCIOUS) { playDeathSound(); } if (_unit->getStatus() == STATUS_UNCONSCIOUS && (_unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH || _unit->getSpecialAbility() == SPECAB_BURN_AND_EXPLODE)) { _unit->instaKill(); } _parent->getMap()->setUnitDying(false); if (_unit->getTurnsSinceSpotted() < 255) { _unit->setTurnsSinceSpotted(255); } if (!_unit->getSpawnUnit().empty()) { // converts the dead zombie to a chryssalid BattleUnit *newUnit = _parent->convertUnit(_unit, _unit->getSpawnUnit()); } else { convertUnitToCorpse(); } _parent->getTileEngine()->calculateUnitLighting(); _parent->popState(); if (_unit->getOriginalFaction() == FACTION_PLAYER && _unit->getSpawnUnit().empty()) { Game *game = _parent->getSave()->getBattleState()->getGame(); if (_unit->getStatus() == STATUS_DEAD) { if (_unit->getArmor()->getSize() == 1) { if (_damageType == DT_NONE) { game->pushState(new InfoboxOKState(game->getLanguage()->getString("STR_HAS_DIED_FROM_A_FATAL_WOUND", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } else if (Options::battleNotifyDeath) { game->pushState(new InfoboxState(game->getLanguage()->getString("STR_HAS_BEEN_KILLED", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } } } else { game->pushState(new InfoboxOKState(game->getLanguage()->getString("STR_HAS_BECOME_UNCONSCIOUS", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } } // if all units from either faction are killed - auto-end the mission. if (_parent->getSave()->getSide() == FACTION_PLAYER && Options::battleAutoEnd) { int liveAliens = 0; int liveSoldiers = 0; _parent->tallyUnits(liveAliens, liveSoldiers, false); if (liveAliens == 0 || liveSoldiers == 0) { _parent->getSave()->setSelectedUnit(0); _parent->cancelCurrentAction(true); _parent->requestEndTurn(); } } } _parent->getMap()->cacheUnit(_unit); }
/* * Think! */ void UnitDieBState::think() { if (_unit->getStatus() == STATUS_TURNING) { _unit->turn(); } else if (_unit->getStatus() == STATUS_STANDING) { _unit->startFalling(); if (!_noSound) { playDeathSound(); } } else if (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } if (_unit->getStatus() == STATUS_DEAD || _unit->getStatus() == STATUS_UNCONSCIOUS) { if (_unit->getStatus() == STATUS_UNCONSCIOUS && _unit->getSpecialAbility() == SPECAB_EXPLODEONDEATH) { _unit->instaKill(); } _parent->getMap()->setUnitDying(false); if (_unit->getTurnsExposed()) { _unit->setTurnsExposed(0); _parent->getSave()->updateExposedUnits(); } if (!_unit->getSpawnUnit().empty()) { // converts the dead zombie to a chryssalid BattleUnit *newUnit = _parent->convertUnit(_unit, _unit->getSpawnUnit()); newUnit->lookAt(_originalDir); } else { convertUnitToCorpse(); } _parent->getTileEngine()->calculateUnitLighting(); _parent->popState(); if (_unit->getOriginalFaction() == FACTION_PLAYER && _unit->getSpawnUnit().empty()) { Game *game = _parent->getSave()->getBattleState()->getGame(); if (_unit->getStatus() == STATUS_DEAD) { if (_damageType == DT_NONE) { std::wstringstream ss; ss << _unit->getName(game->getLanguage()) << L'\n'; ss << game->getLanguage()->getString("STR_HAS_DIED_FROM_A_FATAL_WOUND", _unit->getGender()); game->pushState(new InfoboxOKState(game, ss.str())); } else if (Options::getBool("battleNotifyDeath")) { std::wstringstream ss; ss << _unit->getName(game->getLanguage()) << L'\n'; ss << game->getLanguage()->getString("STR_HAS_BEEN_KILLED", _unit->getGender()); game->pushState(new InfoboxState(game, ss.str())); } } else { std::wstringstream ss; ss << _unit->getName(game->getLanguage()) << L'\n'; ss << game->getLanguage()->getString("STR_HAS_BECOME_UNCONSCIOUS", _unit->getGender()); game->pushState(new InfoboxOKState(game, ss.str())); } } } // if all units from either faction are killed - auto-end the mission. if (Options::getBool("battleAutoEnd")) { int liveAliens = 0; int liveSoldiers = 0; _parent->tallyUnits(liveAliens, liveSoldiers, false); if (liveAliens == 0 || liveSoldiers == 0) { _parent->getSave()->getBattleState()->getBattleGame()->requestEndTurn(); } } _parent->getMap()->cacheUnit(_unit); }
/** * Runs state functionality every cycle. * Progresses the death, displays any messages, checks if the mission is over, ... */ void UnitDieBState::think() { if (_extraFrame == 3) { _parent->popState(); return; } if (_unit->getDirection() != 3 && _damageType != DT_HE) { int dir = _unit->getDirection() + 1; if (dir == 8) { dir = 0; } _unit->lookAt(dir); _unit->turn(); if (dir == 3) { _parent->setStateInterval(BattlescapeState::DEFAULT_ANIM_SPEED); } } else if (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } else if (!_unit->isOut()) { _unit->startFalling(); if (!_noSound) { playDeathSound(); } if (_unit->getRespawn()) { while (_unit->getStatus() == STATUS_COLLAPSING) { _unit->keepFalling(); } } } if (_extraFrame == 2) { _parent->getMap()->setUnitDying(false); _parent->getTileEngine()->calculateUnitLighting(); _parent->popState(); if (_unit->getOriginalFaction() == FACTION_PLAYER) { Game *game = _parent->getSave()->getBattleState()->getGame(); if (_unit->getStatus() == STATUS_DEAD) { if (_damageType == DT_NONE && _unit->getSpawnUnit().empty()) { game->pushState(new InfoboxOKState(game->getLanguage()->getString("STR_HAS_DIED_FROM_A_FATAL_WOUND", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } else if (Options::battleNotifyDeath && _unit->getGeoscapeSoldier() != 0) { game->pushState(new InfoboxState(game->getLanguage()->getString("STR_HAS_BEEN_KILLED", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } } else { game->pushState(new InfoboxOKState(game->getLanguage()->getString("STR_HAS_BECOME_UNCONSCIOUS", _unit->getGender()).arg(_unit->getName(game->getLanguage())))); } } // if all units from either faction are killed - auto-end the mission. if (_parent->getSave()->getSide() == FACTION_PLAYER) { _parent->autoEndBattle(); } } else if (_extraFrame == 1) { _extraFrame++; } else if (_unit->isOut()) { _extraFrame = 1; if (!_noSound && _damageType == DT_HE && _unit->getStatus() != STATUS_UNCONSCIOUS) { playDeathSound(); } if (_unit->getStatus() == STATUS_UNCONSCIOUS && !_unit->getCapturable()) { _unit->instaKill(); } if (_unit->getTurnsSinceSpotted() < 255) { _unit->setTurnsSinceSpotted(255); } if (!_unit->getSpawnUnit().empty()) { // converts the dead zombie to a chryssalid _parent->convertUnit(_unit); } else if (!_noCorpse) { convertUnitToCorpse(); } if (_unit == _parent->getSave()->getSelectedUnit()) { _parent->getSave()->setSelectedUnit(0); } } _parent->getMap()->cacheUnit(_unit); }