/* * This function popups a context sensitive list of actions the user can choose from. * Some actions result in a change of gamestate. * @param item Item the user clicked on (righthand/lefthand) */ void BattlescapeState::handleItemClick(BattleItem *item) { // make sure there is an item, and the battlescape is in an idle state if (item && _states.empty()) { BattleUnit *bu = _battleGame->getSelectedUnit(); // Build up the popup menu int id = 0; std::wstring strAcc = _game->getLanguage()->getString("STR_ACC"); std::wstring strTU = _game->getLanguage()->getString("STR_TUS"); std::wstringstream ss1, ss2; ss1 << strAcc.c_str() << (int)floor(bu->getThrowingAccuracy() * 100) << "%"; ss2 << strTU.c_str() << (int)floor(bu->getUnit()->getTimeUnits() * 0.25); _actionMenu[id]->setAction(BA_THROW, _game->getLanguage()->getString("STR_THROW"), ss1.str(), ss2.str()); _actionMenu[id]->setVisible(true); id++; ss1.str(L""); ss2.str(L""); if (item->getRules()->getAccuracyAuto() != 0) { ss1 << strAcc.c_str() << (int)floor(bu->getFiringAccuracy(item->getRules()->getAccuracyAuto()) * 100) << "%"; ss2 << strTU.c_str() << 0; _actionMenu[id]->setAction(BA_AUTOSHOT, _game->getLanguage()->getString("STR_AUTO_SHOT"), ss1.str(), ss2.str()); _actionMenu[id]->setVisible(true); id++; ss1.str(L""); ss2.str(L""); } if (item->getRules()->getAccuracySnap() != 0) { ss1 << strAcc.c_str() << (int)floor(bu->getFiringAccuracy(item->getRules()->getAccuracySnap()) * 100) << "%"; ss2 << strTU.c_str() << 0; _actionMenu[id]->setAction(BA_SNAPSHOT, _game->getLanguage()->getString("STR_SNAP_SHOT"), ss1.str(), ss2.str()); _actionMenu[id]->setVisible(true); id++; ss1.str(L""); ss2.str(L""); } if (item->getRules()->getAccuracyAimed() != 0) { ss1 << strAcc.c_str() << (int)floor(bu->getFiringAccuracy(item->getRules()->getAccuracyAimed()) * 100) << "%"; ss2 << strTU.c_str() << 0; _actionMenu[id]->setAction(BA_AIMEDSHOT, _game->getLanguage()->getString("STR_AIMED_SHOT"), ss1.str(), ss2.str()); _actionMenu[id]->setVisible(true); id++; ss1.str(L""); ss2.str(L""); } _map->setCursorType(CT_NONE); _popup = true; // TODO other gamestates: scanner/medikit // this should be returned by the popup menu, but is now hardcoded to test without popup menu _selectedItem = item; } }
/** * Update soldier stats when the soldier changes. */ void InventoryState::init() { BattleUnit *unit = _battleGame->getSelectedUnit(); unit->setCache(0); _soldier->clear(); _btnRank->clear(); _txtName->setText(unit->getUnit()->getName(_game->getLanguage())); _inv->setSelectedUnit(unit); Soldier *s = dynamic_cast<Soldier*>(unit->getUnit()); if (s) { SurfaceSet *texture = _game->getResourcePack()->getSurfaceSet("BASEBITS.PCK"); texture->getFrame(s->getRankSprite())->setX(0); texture->getFrame(s->getRankSprite())->setY(0); texture->getFrame(s->getRankSprite())->blit(_btnRank); std::string look = "MAN_0"; if (s->getGender() == GENDER_MALE) look += "M"; else look += "F"; if (s->getLook() == LOOK_BLONDE) look += "0"; if (s->getLook() == LOOK_BROWNHAIR) look += "1"; if (s->getLook() == LOOK_ORIENTAL) look += "2"; if (s->getLook() == LOOK_AFRICAN) look += "3"; look += ".SPK"; _game->getResourcePack()->getSurface(look)->blit(_soldier); } if (_tu) { std::wstringstream ss; ss << _game->getLanguage()->getString("STR_TUS") << L'\x01' << unit->getTimeUnits(); _txtTus->setText(ss.str()); } }
/** * calculateTrajectory. * @return true when a trajectory is possible. */ bool Projectile::calculateTrajectory(double accuracy) { Position originVoxel, targetVoxel; int direction; int dirYshift[8] = {1, 1, 8, 15, 15, 15, 8, 1 }; int dirXshift[8] = {8, 14, 15, 15, 8, 1, 1, 1 }; // large units : x2 originVoxel = Position(_origin.x*16, _origin.y*16, _origin.z*24); originVoxel.z += -_save->getTile(_origin)->getTerrainLevel(); BattleUnit *bu = _save->getTile(_origin)->getUnit(); originVoxel.z += bu->isKneeled()?bu->getUnit()->getKneelHeight():bu->getUnit()->getStandHeight(); originVoxel.z -= 3; if (originVoxel.z >= (_origin.z + 1)*24) { _origin.z++; } direction = bu->getDirection(); originVoxel.x += dirXshift[direction]; originVoxel.y += 15-dirYshift[direction]; // determine the target voxel. // aim at the center of the unit, the object, the walls or the floor (in that priority) // if there is no LOF to the center, try elsewhere (more outward). // Store this target voxel. Tile *tile = _save->getTile(_target); if (tile->getUnit() != 0) { if (_origin == _target) { targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24); } else { targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24 + tile->getUnit()->getUnit()->getStandHeight()/2); } } else if (tile->getMapData(O_OBJECT) != 0) { targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24 + 10); } else if (tile->getMapData(O_NORTHWALL) != 0) { targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 16, _target.z*24 + 10); } else if (tile->getMapData(O_WESTWALL) != 0) { targetVoxel = Position(_target.x*16, _target.y*16 + 8, _target.z*24 + 10); } else if (tile->getMapData(O_FLOOR) != 0) { targetVoxel = Position(_target.x*16 + 8, _target.y*16 + 8, _target.z*24); } else { return false; // no line of fire } // apply some accuracy modifiers (todo: calculate this) // This will results in a new target voxel applyAccuracy(originVoxel, &targetVoxel, accuracy); // finally do a line calculation and store this trajectory. _save->getTerrainModifier()->calculateLine(originVoxel, targetVoxel, true, &_trajectory, bu); return true; }