Amineri Posted September 18, 2013 Share Posted September 18, 2013 While tracing through the various will events I think I've puzzled out a fair bit about how the various Will events works. In an earlier iteration of the game they apparently had copied the Xcom OG / Apoc design and had Psi, Psi Defense, and Will stats tracked separately for each character (these are stats 5, 6, and 7 in the array). However at some point the Psi and Psi Defense stats were dropped and unified into the Will stat. The Will stat is used for both Psi attack, Psi defense, and Morale events. The core function that generates the probability of passing a morale event is WillTestFunction, which is a native function prototyped in XGUnitNativeBase : // Export UXGUnitNativeBase::execWillTestChance(FFrame&, void* const) native simulated function int WillTestChance(int iWillTest, int iMyMods, bool bUseArmorBonus, bool bUseMindShieldBonus, optional XGUnit kVersus, optional int iEvenStatsChanceToFail, optional out int iFinalWill) { iEvenStatsChanceToFail = 50; } It returns the % chance to pass a will test as an int. If it returns 100 there is a 100% chance to succeed, if it returns 0 there is no chance. Since this is a native function I'm not able to look at the actual code to see how this is calculated. I have been able to infer a few things, however. Psionics Psi will tests seem to ignore the iWillTest value and instead use the optional XGUnitkVersus parameter to retrieve the opposed will value. Psi will checks use the default 50% chance to succeed if the attacker's will == the defender's will. This is the value returned and displayed in the UI when starting a psi attack. By altering the defender's will and attacker's will it may be possible to reverse engineer how the WillTestChance function is computing the values. The dev console puts the check at 200 to insure that a Intimidate will test fails. WillTestChance is called directly to compute the display value, as in XGAbility_Targeted.GetUIHitChance : iUIHitChance = m_kUnit.WillTestChance(0, iBonus, true, true, GetPrimaryTarget()); However the psionic attack itself is performed using another route which is done via XGAbility_Targeted.RollForHit : m_bHit = m_kUnit.PassesWillTest(GetPrimaryTarget().m_aCurrentStats[7], iAdjustedChance, true, true, GetPrimaryTarget()); PassesWillTest also calls WillTestChance but performs the roll. One thing of note is that PassesWillTest adds in a +20 for the defender if it is in Combat Drugs cloud, but this modifier is not reflected in the UI hit number displayed. The call in XGUnit.PassesWillTest looks like: iChance = WillTestChance(iWillTest, iMyMods + m_iWillCheatBonus, bUseArmorBonus, bUseMindShieldBonus, kVersus, iEvenStatsChanceToFail); Psionics in vanilla tend to be trivally easy or ridiculously hard to pull off. In part this is because of some strange Will values for units : Sectoid : 10 / 10Floater : 10 / 10Muton : 10 / 10Thin Man : 15 / 15Muton Elite : 20 / 20Outsider : 20 / 20Heavy Floater : 25 / 25Panic Test : various (only 30% to fail chance if equal)Soldier : 40 / 40 (starting)Muton Berserker : 80 / 80Sectoid Commander : 90 / 125Ethereal : 120 / 155Chryssalid : 125 / 125Zombie : 125 / 125Uber Ethereal : 150 / 160 Basically units fall into two categories : Will under 25 (and often only 10!), or will at 80 or higher. This is why it's trivial to psionically affect even Muton Elites and Heavy Floaters. My guess is that these values are for narrative reasons, to explain why some of the alien races are so easily psionically dominated by the Ethereals, but I feel it doesn't make for very good game balance. ----------------------- Morale Morale events work a little bit differently, although ultimately they end up calling the same PassesWillTest -> WillTestChance functions as psi-oriented will tests. Morale events don't have an attacker/defender, though. Instead of a defender they have an EventWill value that is used. The soldier experiencing the morale event uses his/her will as the attacker value. In XGUnit.PerformPanicTest : bPanic = !PassesWillTest(iEventWill, iWillMods, false, false, none, XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.30); Instead of the base 50% chance to succeed, there is only a 30% chance to fail if the unit's will equals the EventWill value. The unit panics if the Will test is failed, meaning that the EventWill must be standing in for the defender's will (higher soldier Will means higher chance to succeed and pass the will test). The EventWill value is retrieved from the function XGTacticalGameCore.CalcWillValue, and the values for each morale event can be modded there. There are two types of Morale Events : squad-based morale events and unit-based morale events. Squad-based ones can affect up to half the squad, but are limited to units that have LOS to the triggering unit. Unit-based ones only affect a single targeted unit. From looking at the enums and the CalcWillValue function here's what I've found for the various morale events and their default EventWill values : 0: Unit is wounded (affects single target) -- EventWill = 151: Unit is Critically Wounded (affects entire squad) -- unsure ... might default to zero?2: Unit is killed (affects entire squad) -- EventWill = 253: Higher ranked unit is killed (modifier for event 2) -- EventWill = 354: Unit is possessed (affects entire squad) -- EventWill = 355: See Zombie Spawn (triggered by OnSeeZombieSpawn) -- EventWill = 456: Unit is panicking (affects entire squad) -- EventWill = 207: Intimidate (affects single target) -- EventWill = 40 In the case of events 2 and 3 the unit's Fallen Comrades will debuff is applied before the will test is applied. The Zombie Spawn morale event is coded so that it can only happen 3 times per battle. It uses the counter m_iZombieMoraleLoss in XGUnit to determine how many morale events this can cause. This happens in XGUnit.OnSeeZombieSpawn. The default value for m_iZombieMoraleLoss is 3, and the counter is decremented each time a soldier sees a zombie spawn. I don't recall this ever happening in game (soldier panicking from seeing a zombie spawn), and the OnSeeZombieSpawn isn't called anywhere from within the upk, so this may be disabled. The higher rank condition for morale event three is that the killed soldier be 3 or more ranks higher than the unit taking the will test. Link to comment Share on other sites More sharing options...
Recommended Posts