* Attempts a panic or mind control action. * @param action Pointer to an action. * @return Whether it failed or succeeded. */
| 2418 | * @return Whether it failed or succeeded. |
| 2419 | */ |
| 2420 | bool TileEngine::psiAttack(BattleAction *action) |
| 2421 | { |
| 2422 | BattleUnit *victim = _save->getTile(action->target)->getUnit(); |
| 2423 | if (!victim) |
| 2424 | return false; |
| 2425 | double attackStrength = action->actor->getStats()->psiStrength * action->actor->getStats()->psiSkill / 50.0; |
| 2426 | double defenseStrength = victim->getStats()->psiStrength |
| 2427 | + ((victim->getStats()->psiSkill > 0) ? 10.0 + victim->getStats()->psiSkill / 5.0 : 10.0); |
| 2428 | double d = distance(action->actor->getPosition(), action->target); |
| 2429 | attackStrength -= d; |
| 2430 | attackStrength += RNG::generate(0,55); |
| 2431 | |
| 2432 | if (action->type == BA_MINDCONTROL) |
| 2433 | { |
| 2434 | defenseStrength += 20; |
| 2435 | } |
| 2436 | |
| 2437 | action->actor->addPsiExp(); |
| 2438 | if (attackStrength > defenseStrength) |
| 2439 | { |
| 2440 | action->actor->addPsiExp(); |
| 2441 | action->actor->addPsiExp(); |
| 2442 | if (action->type == BA_PANIC) |
| 2443 | { |
| 2444 | int moraleLoss = (110-_save->getTile(action->target)->getUnit()->getStats()->bravery); |
| 2445 | if (moraleLoss > 0) |
| 2446 | _save->getTile(action->target)->getUnit()->moraleChange(-moraleLoss); |
| 2447 | } |
| 2448 | else// if (action->type == BA_MINDCONTROL) |
| 2449 | { |
| 2450 | victim->convertToFaction(action->actor->getFaction()); |
| 2451 | calculateFOV(victim->getPosition()); |
| 2452 | calculateUnitLighting(); |
| 2453 | victim->setTimeUnits(victim->getStats()->tu); |
| 2454 | victim->allowReselect(); |
| 2455 | victim->abortTurn(); // resets unit status to STANDING |
| 2456 | // if all units from either faction are mind controlled - auto-end the mission. |
| 2457 | if (_save->getSide() == FACTION_PLAYER && Options::battleAutoEnd && Options::allowPsionicCapture) |
| 2458 | { |
| 2459 | int liveAliens = 0; |
| 2460 | int liveSoldiers = 0; |
| 2461 | _save->getBattleGame()->tallyUnits(liveAliens, liveSoldiers, false); |
| 2462 | if (liveAliens == 0 || liveSoldiers == 0) |
| 2463 | { |
| 2464 | _save->setSelectedUnit(0); |
| 2465 | _save->getBattleGame()->cancelCurrentAction(true); |
| 2466 | _save->getBattleGame()->requestEndTurn(); |
| 2467 | } |
| 2468 | } |
| 2469 | } |
| 2470 | return true; |
| 2471 | } |
| 2472 | return false; |
| 2473 | } |
| 2474 | |
| 2475 | /** |
| 2476 | * Applies gravity to a tile. Causes items and units to drop. |
no test coverage detected