The problem.
I'm sure, Psi Attack is too easy in OpenXcom.
Formula Psi Attacks in vanilla Xcom:
Attack Strength (AS) = INT(Psi Strength * Psi Skill / 50) Attacker stats
Defense Strength (DS) = INT(Psi Strength + (Psi Skill / 5)) Defender stats
Attack Success (A%) = 100/56 * (Constant + AS – DS – Distance)
where: Constant = 25 for Mind Control; 45 for Panic
https://www.ufopaedia.org/index.php?title=PsionicsIn one string, formula for Mind Control:
A% = 100/56 * (25 + INT(APSt * APSk / 50) – INT(DPSt + DPSk / 5) – Distance)
If A% < 0 then attack always fail. If A% > 100 then attack always successful.
For example:
My unit: APSt = 90; APSk = 30.
Victim – Sectoid: DPSt = 40; DPSk = 50.
Distance: 20.
Attack Success: A% = 16,07%
Formula Psi Attacks in OpenXcom:
double attackStrength = action->actor->getStats()->psiStrength * action->actor->getStats()->psiSkill / 50;
double defenseStrength = victim->getStats()->psiStrength + 30 + (victim->getStats()->psiSkill / 5);
int d = distance(action->actor->getPosition(), action->target);
attackStrength -= d/2;
attackStrength += RNG::generate(0,55);
…
else if (action->type == BA_MINDCONTROL)
{
if (attackStrength > defenseStrength)
{
https://github.com/SupSuper/OpenXcom/blob/master/src/Battlescape/TileEngine.cpp#L1780APSt * APSk / 50 – Distance / 2 + RNG(0,55) > DPSt + 30 + DPSk / 5
Or, after transformation:
A% = 100/55 * (25 + APSt * APSk / 50 – (DPSt + DPSk / 5) – Distance / 2)
No difference between "Mind control" and "Panic" attacks!
Example:
My unit: APSt = 90; APSk = 30.
Victim – Sectoid: DPSt = 40; DPSk = 50.
Distance: 20.
Attack Success: A% = 34,55%
OpenXcom easier to play versus vanilla Xcom.
The suggestion.
1. Suggest to use formula such as in original Xcom. Should be a difference between "Mind control" and "Panic" attacks.
2. Suggest to give less experience points for "Panic" attack, and only if attack is successful. This will reduce the possibility of training exploit.
For example:
if (action->type == BA_PANIC)
{
if (attackStrength > defenseStrength)
{
[b]action->actor->addPsiExp();[/b]
int moraleLoss = (110-_save->getTile(action->target)->getUnit()->getStats()->bravery);
if (moraleLoss > 0)
_save->getTile(action->target)->getUnit()->moraleChange(-moraleLoss);
return true;
}
else
{
return false;
}
}
3. Can be added to the formula unit Morale.
For example:
A% = 100/56 * (Const - (Morale / 10) + (APSt * APSk / 50) – (DPSt + DPSk / 5) – Distance)
where: Const = 33 for Mind control; 53 for Panic attack.
My unit: APSt = 90; APSk = 30.
Victim – Sectoid: DPSt = 40; DPSk = 50; Morale = 80.
Distance: 20.
Attack Success: A% = 16,07%