Jump to content
ℹ️ Intermittent Download History issues ×

DCG.ini Exalt weapon


bestliutr

Recommended Posts

I need help with modding the EXALT weapons

I was trying to improve exalt weapon usefulness by copy/pasting the properties of the next tier(exalt normal=laser, exalt laser=plasma)

I was successful in the barracks view

http://puu.sh/5M7oH.jpg

but here is the problem, the damage in game didn't actually change

http://puu.sh/5M7Bl.jpg

And the actual damage didn't change. Did I do something wrong?

Link to comment
Share on other sites

My initial suspicion on seeing this is that the EXALT weapons are set up to map to the vanilla weapons with the GameplayType() function.

 

The root of the issue as that at the (near-)root class XGItem (from which XGWeapon decends) there are two different methods provided to retrieve an items integer value (which maps to the enumeration EItemType).

 

  • ItemType() -- this is a non-native function that returns the default.m_eType of the class
    • It's not actually possible to change m_eType as there is no setter method (and the default. tag would prevent the new value from being used)
    • Instead each weapon is configured like:
class XGWeapon_ExaltAssaultRifle extends XGWeapon
    hidecategories(Navigation)
    notplaceable;

defaultproperties
{
    iCursorType=ECursorType.eXGCursor_Rifle
    m_eType=EItemType.eItem_ExaltAssaultRifle
    m_strUIImage="WP_AssaultRifleModern_ICON.IC_AssaultRifleModern"
}

So ItemType directly returns the item enum value, which distinguishes alien weapon versions (e.g. XGWeapon_PlasmaLightRifle_ThinMan ) from the base variants (e.g. XGWeapon_PlasmaLightRifle).

 

 

  • GameplayType() -- this is a native function so I can't observe directly what it is doing, but it is used in places such as XGAbility_Targeted.CalcDamage :
m_iActualDamage = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CalcOverallDamage(m_kWeapon.GameplayType(), m_kUnit.m_aCurrentStats[12], m_bCritical, m_bReflected);

In particular note the use of m_kWeapon.GameplayType() instead of m_kWeapon.ItemType(). For alien weapons (e.g. Thin Man LPR) to be seen as the "common" variant.

 

I'm pretty sure that GameplayType() is mapping the EXALT variants to the standard variants because of the following lines in XGSummaryUI.CollectArtifactsFromDeadAliens:

                            if(kAlien.IsExalt())
                            {
                                iItem = kItem.ItemType();
                            }
                            // End:0x6A7
                            else
                            {
                                iItem = kItem.GameplayType();
                            }

The only reason to have this is to allow the collection of Exalt weapons after a battle -- it strongly implies that an EXALT weapon's GameplayType() maps to the 'standard' type.

 

Why Firaxis went to so much trouble to create 2 new lines of weapons and then went out of their way to make them function identically to weapons already in the game? I have no idea ...

 

 

------------------------

 

There are a ways around this.

 

1) The quickest (but possibly with the most repercussions) is to change the above line to use ItemType() instead of GameplayType(). This will cause all weapons to use the damage from the weapon-variant statline in the DGC.ini. So Muton LPRs vs Thin Man LPRs vs. Floater LPRs vs XCOM LPRs could all directly be given different damage amounts.

 

This also wouldn't affect all the other ways that GameplayType() mappings are used (e.g. to grant +10 aim bonus to ThinMan LPRs)

 

The usage of GameplayType() could be changed to ItemType() in more places, but it is used a LOT. I counted no less than 77 usages in XComGame.upk.

 

 

2) Alternatively the GameplayType() function could be rebuilt out of an unused unrealscript function. Unfortunately XGItem class has only 5 method in total, 2 of which are native functions. Unless we can some expand (using wghost81's method) and rebuild a native function directly into a non-native function we may be out of luck on this approach.

 

However it might be possible to re-build the function out of one of the child classes, perhaps in XGInventoryItem or XGWeapon.

Link to comment
Share on other sites

Thank you for digging into it, i had the same suspicion and tried altering the normal version of the weapon and found the same thing.

 

I understand what you mean, but I kind of feel this is beyond my current ability. I haven't figure out how to find the hex code i need to edit and what I need to change it to. I've been searching for a tutorial but haven't found any that is helpful.

Link to comment
Share on other sites

Sorry I didn't post any hex but I've been so busy working on some new modding tools that I still hadn't updated XCOM to the EU patch 6 / EW patch 1 version. I'm doing that today and will post up some test EW patch 1 hex so it can be tested.

 

Regarding learning how to code in hex:

 

There are some decent wiki articles, but learning through a book is oftentimes one of the harder ways to do it.

Link to comment
Share on other sites

Here is a hex patch that should make all alien and EXALT weapons deal damage based on their particular DGC.ini weapon entries instead of using the generic version.

 

There may be some oddness because of the native CalcOverallDamageModFromPerks function (which may be reading the weapon damage again using the GameplayType())

 

 

 

MODFILEVERSION=3
UPKFILE=XComGame.upk 
GUID=5B 06 B8 18 67 22 12 44 85 9B A8 5B 9D 57 1D 4B // XComGame_EW_patch1.upk
FUNCTION=CalcDamage@XGAbility_Targeted
// Unlock weapon damage
// Makes it so that all weapons (EXALT AND Alien) use the DGC.ini entries for damage instead of being mapped to the "common" weapon type.
// Author: Amineri 
[BEFORE_HEX]
[CODE]
//m_iActualDamage = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CalcOverallDamage(m_kWeapon.GameplayType(), m_kUnit.m_aCurrentStats[12], m_bCritical, m_bReflected)
0F 01 DC D2 00 00 19 19 2E 2D 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 1F 32 00 00 00 01 1F 32 00 00 60 00 19 84 00 00 00 1B CB 10 00 00 00 00 00 00 38 3A 19 01 AE D2 00 00 0A 00 CC B9 00 00 00 1B 8B 36 00 00 00 00 00 00 16 1A 2C 0C 19 01 27 89 00 00 09 00 38 3A 00 00 00 01 38 3A 00 00 2D 01 EB D2 00 00 2D 01 EA D2 00 00 16 
[/CODE]
[/BEFORE_HEX]

[AFTER_HEX]
[CODE]
//m_iActualDamage = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CalcOverallDamage(m_kWeapon.ItemType(), m_kUnit.m_aCurrentStats[12], m_bCritical, m_bReflected)
0F 01 DC D2 00 00 19 19 2E 2D 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 1F 32 00 00 00 01 1F 32 00 00 60 00 19 84 00 00 00 1B CB 10 00 00 00 00 00 00 38 3A 19 01 AE D2 00 00 0A 00 C8 B9 00 00 00 1B 5C 46 00 00 00 00 00 00 16 1A 2C 0C 19 01 27 89 00 00 09 00 38 3A 00 00 00 01 38 3A 00 00 2D 01 EB D2 00 00 2D 01 EA D2 00 00 16 
[/CODE]
[/AFTER_HEX] 

 

 

 

Just FYI to anyone interested this is the format that I plan on releasing my mods in the future. This format allows for fairly simple mostly automated updating for new patches. We have eventual plans to add export capability for various mod installer formats but that's down the road. Not to mention that trying to release every mod in three of four formats would be a bit of a pain.

 

As a test I actually created this mod using the EW release hex and then updated it (verifying that in fact none of the references had changed).

 

 

For anyone that is interested (for educational purposes) here is the same change but with all of the 4-byte references changed into full name:

 

 

 

MODFILEVERSION=3
UPKFILE=XComGame.upk 
GUID=UNSPECIFIED // no hex references in file
FUNCTION=CalcDamage@XGAbility_Targeted
// Unlock weapon damage
// Makes it so that all weapons (EXALT AND Alien) use the DGC.ini entries for damage instead of being mapped to the "common" weapon type.
// Author: Amineri 
[BEFORE_HEX]
[CODE]
//m_iActualDamage = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CalcOverallDamage(m_kWeapon.GameplayType(), m_kUnit.m_aCurrentStats[12], m_bCritical, m_bReflected)
0F 01 {|m_iActualDamage@XGAbility_Targeted|} 19 19 2E {|XComGameReplicationInfo|} 19 12 20 {|Core:Engine@Engine|} 0A 00 {|Core:ReturnValue@GetCurrentWorldInfo@Engine@Engine|} 00 1C {|Core:GetCurrentWorldInfo@Engine@Engine|} 16 09 00 {|Core:GRI@WorldInfo@Engine|} 00 01 {|Core:GRI@WorldInfo@Engine|} 09 00 {|m_kGameCore@XComGameReplicationInfo|} 00 01 {|m_kGameCore@XComGameReplicationInfo|} 60 00 {|ReturnValue@CalcOverallDamage@XGTacticalGameCore|} 00 1B <|CalcOverallDamage|> 00 00 00 00 38 3A 19 01 {|m_kWeapon@XGAbility_Targeted|} 0A 00 {|ReturnValue@GameplayType@XGItem|} 00 1B <|GameplayType|> 00 00 00 00 16 1A 2C 0C 19 01 {|m_kUnit@XGAbility|} 09 00 {|m_aCurrentStats@XGUnitNativeBase|} 00 01 {|m_aCurrentStats@XGUnitNativeBase|} 2D 01 {|m_bCritical@XGAbility_Targeted|} 2D 01 {|m_bReflected@XGAbility_Targeted|} 16 
[/CODE]
[/BEFORE_HEX]

[AFTER_HEX]
[CODE]
//m_iActualDamage = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CalcOverallDamage(m_kWeapon.ItemType(), m_kUnit.m_aCurrentStats[12], m_bCritical, m_bReflected)
0F 01 {|m_iActualDamage@XGAbility_Targeted|} 19 19 2E {|XComGameReplicationInfo|} 19 12 20 {|Core:Engine@Engine|} 0A 00 {|Core:ReturnValue@GetCurrentWorldInfo@Engine@Engine|} 00 1C {|Core:GetCurrentWorldInfo@Engine@Engine|} 16 09 00 {|Core:GRI@WorldInfo@Engine|} 00 01 {|Core:GRI@WorldInfo@Engine|} 09 00 {|m_kGameCore@XComGameReplicationInfo|} 00 01 {|m_kGameCore@XComGameReplicationInfo|} 60 00 {|ReturnValue@CalcOverallDamage@XGTacticalGameCore|} 00 1B <|CalcOverallDamage|> 00 00 00 00 38 3A 19 01 {|m_kWeapon@XGAbility_Targeted|} 0A 00 {|ReturnValue@ItemType@XGItem|} 00 1B <|ItemType|> 00 00 00 00 16 1A 2C 0C 19 01 {|m_kUnit@XGAbility|} 09 00 {|m_aCurrentStats@XGUnitNativeBase|} 00 01 {|m_aCurrentStats@XGUnitNativeBase|} 2D 01 {|m_bCritical@XGAbility_Targeted|} 2D 01 {|m_bReflected@XGAbility_Targeted|} 16 
[/CODE]
[/AFTER_HEX] 

 

 

 

These are fully specified, unambiguous references, so :

{|ReturnValue@CalcOverallDamage@XGTacticalGameCore|}

means the ReturnValue variable of the CalcOverallDamage function in the XGTacticalGameCore class

Link to comment
Share on other sites

Greetings.

 

I too always wondered why the Exalt Weapons didnt seem to update correctly to the changes made in DCG.ini. Who would´ve thought some cryptic, over-complicated redundant function to be the culprit. :dry:

 

EDIT: Never mind, Amineri got it working. :blush:

 

UPDATE: Just tested the aforementioned changes to "XGAbility_Targeted". Unfortunately, the "does up to x damage" dialog ingame still shows the default values, instead of the ones specified in DGC.ini.

 

However, the damage applied when firing IS indeed updated correctly. For testing purposes, I temporarily upgraded the EXALT Assault Rifle to 20 damage, and promptly scored a whooping 45 damage critical on an unlucky muton. :nuke:

Edited by RandomUser123
Link to comment
Share on other sites

The damage display was something that vexed us in Long War, and we weren't able to really deal with even up through the v2.12 final version for EU.

 

The following delves in pretty deep and is not pretty, but it's the best I've been able to figure out.

 

The Possible Damage displayed is replaced during a display substitution script that looks like :

    HelpMessages[7]="Does up to <XGAbility:PossibleDamage/> damage."

There are quite a few more messages that use the <XGAbility:PossibleDamage/> field :

 

 

    HelpMessages[11]="Self-destruct, causing <XGAbility:PossibleDamage/> damage to nearby units."
    HelpMessages[16]="Does <XGAbility:PossibleDamage/> damage."
    HelpMessages[18]="Does <XGAbility:PossibleDamage/> damage."
    HelpMessages[19]="Does <XGAbility:PossibleDamage/> damage."
    HelpMessages[48]="Does up to <XGAbility:PossibleDamage/> damage. Increased chance of a critical hit."
    HelpMessages[49]="Does up to <XGAbility:PossibleDamage/> damage. Causes target's main weapon to malfunction."
    HelpMessages[52]="Does <XGAbility:PossibleDamage/> damage and causes targets to take increased damage from all sources."
    HelpMessages[79]="Does <XGAbility:PossibleDamage/> damage to units not in cover."
    HelpMessages[80]="Does <XGAbility:PossibleDamage/> fire damage to units in the damage cone, and spills to one extra tile at cone's edge. Causes panic in enemies and sets fire to the environment."
    HelpMessages[81]="A melee attack that does <XGAbility:PossibleDamage/> damage to enemies and can destroy cover."
    HelpMessages[82]="Plant a mine that does <XGAbility:PossibleDamage/> damage to enemies that move within the mine's detection radius"
    HelpMessages[84]="Destroy the target's cover and do up to <XGAbility:PossibleDamage/> damage. No critical chance."
    HelpMessages[86]="Fire a grenade that does up to <XGAbility:PossibleDamage/> damage to enemies and destroys terrain"
    HelpMessages[88]="Affects all units near the MEC, inflicting <XGAbility:PossibleDamage/> damage. Robotic units are also disabled for one turn."

 

 

 

Suffice to say that trying to replace the message strings and directly put in the possible damage (for all weapon/ability pairings) isn't realistic.

 

So the XGAbility class has a class variable iPossibleDamage that looks like it must be where the text replacement script is pulling the number from. The problem is that XGAbility.iPossibleDamage is never set nor accessed in the whole XGAbility class. Not only that, but XGAbility does not contain any way to reference a particular weapon on which to base Possible Damage.

 

However, XGAbility has an important child class, XGAbility_Targeted. And XGAbility_Targeted does contain a class variable m_kWeapon. XGAbility_Targeted is where both damage and ammo cost are computed, so I've modded this class fairly heavily in the past in order to change both of those things. It even includes a method GetPossibleDamage() which simple returns the class variable iPossibleDamage inherited from XGAbility. However, there is no setter method, nor is iPossibleDamage ever set within the visible unreal script in XComGame.upk.

 

Far away from these classes in XGTacticalGameCoreNative base is a native function :

// Export UXGTacticalGameCoreNativeBase::execCalcPossibleDamage(FFrame&, void* const)
native simulated function int CalcPossibleDamage(int iWeapon, int iAbility, out TCharacter kCharacter, out int aCurrentStats[ECharacterStat], out int iTargetDefense, optional bool bOverload, optional bool bCritical, optional bool bHasHeightBonus, optional float fDistanceToTarget, optional bool bUseFlankBonus, optional bool bReactionFire)
{
    bOverload = false;
    bCritical = false;
    bHasHeightBonus = false;
    fDistanceToTarget = 0.0;
    bUseFlankBonus = false;
    bReactionFire = false;                                                    
}

This certainly looks like a promising utility function that could be computing iPossibleDamage. Access would be through XGAbility.m_kGameCore which contains a link to the XGTacticalGameCore child class.

 

CalcPossibleDamage directly accepts the weapon enum, which means that any conversion via the GameplayType() function would be done prior to calling CalcPossibleDamage. Unfortunately a quick search reveals that not only is CalcPossibleDamage a native function, but it is never called from XComGame.upk. This can only mean that the method calling it is also a native function...

 

So, I started trying to figure out what native function CalcPossibleDamage might be getting called from. It has to be getting the info from somewhere ... My current best guess is the function in XGAbility_Targeted :

// Export UXGAbility_Targeted::execShotInit(FFrame&, void* const)
native function ShotInit(int iAbility, array<XGUnit> arrTargets, XGWeapon kWeapon, optional bool bReactionFire)
{
    bReactionFire = false;                        
}

The name sounds likely and it contains all of the information needed to initialize the XGAbility_Targeted data elements, including calling CalcPossibleDamage in order to set iPossibleDamage.

 

And then things got even uglier... ShotInit does not have any calls to generically initiate XGAbility_Targeted. There are only 3 calls (non-debug) in XComGameCore :

  1. XGUnit.AddPsiReflectAction -- inits and immediately creates a reflected shot when Ethereals use their psionic reflect ability
  2. XGAbility_Grapple.ShotInit -- an override method
  3. XGAbility_Fly.ShotInit -- another override method

 

My best guess as to where XGAbility_Targeted.ShotInit is being called is in XGUnitNativeBase.BuildAbilities :

// Export UXGUnitNativeBase::execBuildAbilities(FFrame&, void* const)
native function BuildAbilities(optional bool bUpdateUI)
{
    bUpdateUI = false;            
} 

not to be confused with XGAbilityTree.BuildAbilities (which builds the set of ability templates).

 

This appears to be the function that actually builds the array of current abilities the unit can use:

repnotify XGAbility m_aAbilities[64]

The unit version of BuildAbilities appears to be called quite a few places throughout the code (e.g. after using Run and Gun, BuildAbilities is called to rebuild which abilities the unit can use, which is how the restriction on using items after Run and Gun is implemented).

 

So the call chain appears to be:

  1. Some method calls XGUnitNativeBase.BuildAbilities (native code)
  2. XGUnitNativeBase.BuildAbilities spawns the appropriate XGAbility_Targeted classes and calls XGAbility_Targeted.ShotInit (native code)
  3. XGAbility_Targeted.ShotInit calls m_kGameCore.CalcPossibleDamage (native Code)
    • This call is likely where the GameplayType() method is being used to retrieve the weapon enum to pass to CalcPossibleDamage
  4. CalcPossibleDamage sets the iPossibleDamage class variable inherited from XGAbility
  5. iPossibleDamage is used for display either directly or through the GetPossibleDamage method by the text replacement script

This is a pretty ugly chain of calls through a lot of native code, but it may still be possible to intercept and correct the Possible Damage.

 

If an "extra" function in XGAbility_Targeted could be used to override the usual ShotInfo method with the code :

simulated function ShotInit(int iAbility, array<XGUnit> arrTargets, XGWeapon kWeapon, optional bool bReactionFire)
{
    bReactionFire = false;
    oldShotInit(iAbility, arrTargets, kWeapon, bReactionFire);
    m_kGameCore.CalcPossibleDamage(kWeapon.ItemType(), iAbility, m_kUnit.GetCharacter(), m_kUnit.m_aCurrentStats, GetPrimaryTarget().getDefense());
}

Alternatively I'm thinking it might be worthwhile to explore whether a native function call can be increased in size (via wghost81's method) and turned into a non-native function.

 

The existing Buffer Entry for CalcPossibleDamage is :

A3 10 00 00 76 5F 00 00 00 00 00 00 97 10 00 00 
00 00 00 00 00 00 00 00 A3 10 00 00 00 00 00 00 
F6 05 00 00 7D EA 00 00 87 00 00 00 5B 00 00 00 
49 02 00 28 15 49 02 00 28 15 49 02 00 28 15 49 
06 00 1E 00 00 00 00 15 49 02 00 28 15 49 02 00 
28 15 29 A3 10 00 00 29 A2 10 00 00 29 A1 10 00 
00 29 A0 10 00 00 29 9F 10 00 00 29 9E 10 00 00 
29 9D 10 00 00 29 9C 10 00 00 29 9B 10 00 00 29 
9A 10 00 00 29 99 10 00 00 0B 53 00 00 00 00 45 
42 00 CF 10 00 00 00 00 00 00

The actual "body" of the function consists of :

49 02 00 28 15 -- DefaultParmValue, false
49 02 00 28 15 -- DefaultParmValue, false
49 02 00 28 15 -- DefaultParmValue, false
49 06 00 1E 00 00 00 00 15 -- DefaultParmValue, 0.0
49 02 00 28 15 -- DefaultParmValue, false
49 02 00 28 15 -- DefaultParmValue, false
29 A3 10 00 00 -- NativeParm, reference
29 A2 10 00 00 -- NativeParm, reference
29 A1 10 00 00 -- NativeParm, reference
29 A0 10 00 00 -- NativeParm, reference
29 9F 10 00 00 -- NativeParm, reference
29 9E 10 00 00 -- NativeParm, reference
29 9D 10 00 00 -- NativeParm, reference
29 9C 10 00 00 -- NativeParm, reference
29 9B 10 00 00 -- NativeParm, reference
29 9A 10 00 00 -- NativeParm, reference
29 99 10 00 00 -- NativeParm, reference
0B -- null op
53 -- end of script

Unfortunately I haven't been able to find the flag (or flags) that will switch a native type function to a regular simulated function.

Link to comment
Share on other sites

Thats some impressive digging, Amineri. Personally, I can live with the damage display being slightly incorrect, considering it really being only a minor, cosmetic annoyance in the grand scheme of things.

 

On another note, I´ve noticed a pretty substantial side-effect when playing with the new "XGAbility_Targeted": NPC grenades in general only deal 1 point of damage. This includes frags from EXALT troopers, the mutons alien grenades, and those spiffy little detonators the cyberdisc sometimes lashes out.

 

Probably because their individual damage values are no longer read out of the respective functions, and thus default to 1 point.

Link to comment
Share on other sites

Oh, right, that makes sense! (in hindsight...)

 

One of the issues I had with the "New Items" mod for EU was that some of the seemingly 'extra' item enumerations are actually used. In particular:

90	0x5a	eItem_SectoidGrenade
91	0x5b	eItem_FloaterGrenade
92	0x5c	eItem_MutonGrenade	
93	0x5d	eItem_CyberdiscGrenade	
94	0x5e	eItem_ThinManGrenade	

Making new XCOM-equipable items led to a variety of weird glitches so we ended up just leaving them alone. However since ItemType() is now being passed into damage it is attempting to draw the damage values for these items from the entries in the DGC.ini -- and there aren't any entries :). Everything does a minimum of 1 damage if it hits (even though 0 is getting passed in), which is why you are seeing 1 damage consistently.

 

 

Fixing this should be as simple as adding some additional lines to the DGC.ini :

Weapons=( strName="", iType=eItem_MutonGrenade,             ABILITIES[0]=eAbility_AlienGrenade,   ABILITIES[1]=eAbility_NONE,                ABILITIES[2]=eAbility_NONE,         ABILITIES[3]=eAbility_NONE,      ABILITIES[4]=eAbility_NONE, ABILITIES[5]=eAbility_NONE, Properties[0]=eWP_AnyClass,   Properties[1]=eWP_Secondary,     Properties[2]=eWP_NoReload,      Properties[3]=eWP_Explosive, Properties[4]=eWP_None,        Properties[5]=eWP_None, iDamage=5,  iEnvironmentDamage=250, iRange=17,  iReactionRange=-1, iReactionAngle=200, iRadius=240,  iCritical=0,  iOffenseBonus=0,  iSuppression=0,  iSize=eItemSize_Small, iHPBonus=0, iWillBonus=0 ) 
Weapons=( strName="", iType=eItem_CyberdiscGrenade,             ABILITIES[0]=eAbility_AlienGrenade,   ABILITIES[1]=eAbility_NONE,                ABILITIES[2]=eAbility_NONE,         ABILITIES[3]=eAbility_NONE,      ABILITIES[4]=eAbility_NONE, ABILITIES[5]=eAbility_NONE, Properties[0]=eWP_AnyClass,   Properties[1]=eWP_Secondary,     Properties[2]=eWP_NoReload,      Properties[3]=eWP_Explosive, Properties[4]=eWP_None,        Properties[5]=eWP_None, iDamage=5,  iEnvironmentDamage=250, iRange=17,  iReactionRange=-1, iReactionAngle=200, iRadius=240,  iCritical=0,  iOffenseBonus=0,  iSuppression=0,  iSize=eItemSize_Small, iHPBonus=0, iWillBonus=0 ) 
Weapons=( strName="", iType=eItem_FloaterGrenade,             ABILITIES[0]=eAbility_AlienGrenade,   ABILITIES[1]=eAbility_NONE,                ABILITIES[2]=eAbility_NONE,         ABILITIES[3]=eAbility_NONE,      ABILITIES[4]=eAbility_NONE, ABILITIES[5]=eAbility_NONE, Properties[0]=eWP_AnyClass,   Properties[1]=eWP_Secondary,     Properties[2]=eWP_NoReload,      Properties[3]=eWP_Explosive, Properties[4]=eWP_None,        Properties[5]=eWP_None, iDamage=5,  iEnvironmentDamage=250, iRange=17,  iReactionRange=-1, iReactionAngle=200, iRadius=240,  iCritical=0,  iOffenseBonus=0,  iSuppression=0,  iSize=eItemSize_Small, iHPBonus=0, iWillBonus=0 ) 

I think FloaterGrenade is necessary in order to give the Heavy Floaters their grenades.

 

 

I'm not sure why EXALT frag grenades would be getting messed up, as there doesn't seem to be an item type for EXALT-specific frag grenades.

 

According the DefaultLoadouts.ini :

  • The only non-elite EXALT that gets a damaging grenade is the Operative, who is loaded out with : arrSmallItems[0]=eItem_FragGrenade
  • Elite Operatives and Heavies are supposed to be loaded out with : arrSmallItems[0]=eItem_AlienGrenade
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...