Skip to content

Commit

Permalink
Issue #1057 - implement IsWeaponAllowedByClass_CH() and `GetAllowed…
Browse files Browse the repository at this point in the history
…ClassForWeapon_CH()`
  • Loading branch information
Iridar committed Mar 2, 2022
1 parent 0518418 commit ee3ed07
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,9 @@ simulated function string GetDisabledReason(XComGameState_Item Item, EInventoryS
if(WeaponTemplate != none)
{
SoldierClassTemplate = UpdatedUnit.GetSoldierClassTemplate();
if(SoldierClassTemplate != none && !SoldierClassTemplate.IsWeaponAllowedByClass(WeaponTemplate))
if(SoldierClassTemplate != none && !SoldierClassTemplate.IsWeaponAllowedByClass_CH(WeaponTemplate, SelectedSlot)) // Issue #1057 - call IsWeaponAllowedByClass_CH() instead of the original.
{
AllowedSoldierClassTemplate = class'UIUtilities_Strategy'.static.GetAllowedClassForWeapon(WeaponTemplate);
AllowedSoldierClassTemplate = class'UIUtilities_Strategy'.static.GetAllowedClassForWeapon_CH(WeaponTemplate, SelectedSlot);
if(AllowedSoldierClassTemplate == none)
{
DisabledReason = m_strMissingAllowedClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,13 @@ simulated function name PopulateItemDropdown(UIDropdown kDropdown, name nCurrent
continue;
if( X2EquipmentTemplate(kEquipmentTemplate) != none &&
X2EquipmentTemplate(kEquipmentTemplate).iItemSize > 0 && // xpad is only item with size 0, that is always equipped
((X2EquipmentTemplate(kEquipmentTemplate).InventorySlot == eEquipmentType) || (X2EquipmentTemplate(kEquipmentTemplate).InventorySlot == eInvSlot_Utility && eEquipmentType == eInvSlot_GrenadePocket)))
((X2EquipmentTemplate(kEquipmentTemplate).InventorySlot == eEquipmentType) || (X2EquipmentTemplate(kEquipmentTemplate).InventorySlot == eInvSlot_Utility && eEquipmentType == eInvSlot_GrenadePocket))
// Single Line for Issue #1057 - allow any primary or secondary weapon so that IsWeaponAllowedByClass_CH() can decide which weapons to show.
|| (kEquipmentTemplate.IsA('X2WeaponTemplate') && (eEquipmentType == eInvSlot_PrimaryWeapon || eEquipmentType == eInvSlot_SecondaryWeapon)))
{
if (kSoldierClassTemplate != None && kEquipmentTemplate.IsA('X2WeaponTemplate'))
{
if (!kSoldierClassTemplate.IsWeaponAllowedByClass(X2WeaponTemplate(kEquipmentTemplate)))
if (!kSoldierClassTemplate.IsWeaponAllowedByClass_CH(X2WeaponTemplate(kEquipmentTemplate), eEquipmentType))
{
if (nCurrentEquipped == kEquipmentTemplate.DataName)
nCurrentEquipped = '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,32 @@ simulated static function X2SoldierClassTemplate GetAllowedClassForWeapon(X2Weap
}
}

// Start Issue #1057
/// HL-Docs: ref:IsWeaponAllowedByClass
///
/// # GetAllowedClassForWeapon_CH()
///
/// Similarly to `IsWeaponAllowedByClass_CH()`, a `GetAllowedClassForWeapon_CH()` function was created
/// to find a soldier class template of a class that is allowed to use a weapon of the specified template
/// in the specified inventory slot, rather than in the slot specified in the weapon template itself.
///
/// # Compatibility
///
/// For the sake of consistency, it is preferable that mods call `GetAllowedClassForWeapon_CH()` rather than `GetAllowedClassForWeapon()` whenever possible.
simulated static final function X2SoldierClassTemplate GetAllowedClassForWeapon_CH(X2WeaponTemplate WeaponTemplate, optional EInventorySlot InventorySlot)
{
local X2DataTemplate DataTemplate;
local X2SoldierClassTemplate SoldierClassTemplate;

foreach class'X2SoldierClassTemplateManager'.static.GetSoldierClassTemplateManager().IterateTemplates(DataTemplate, none)
{
SoldierClassTemplate = X2SoldierClassTemplate(DataTemplate);
if(SoldierClassTemplate.IsWeaponAllowedByClass_CH(WeaponTemplate, InventorySlot))
return SoldierClassTemplate;
}
}
// End Issue #1057

simulated static function X2SoldierClassTemplate GetAllowedClassForArmor(X2ArmorTemplate ArmorTemplate)
{
local X2DataTemplate DataTemplate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,50 @@ function bool IsWeaponAllowedByClass(X2WeaponTemplate WeaponTemplate)
return false;
}

// Start Issue #1057
/// HL-Docs: feature:IsWeaponAllowedByClass; issue:1057; tags:strategy,compatibility
/// When the game needs to determine whether a weapon with particular category
/// can be used by a particular soldier class, it calls the `IsWeaponAllowedByClass()` function,
/// which checks whether the weapon is allowed in the inventory slot specified in the Weapon Template.
///
/// This is a problem, because there are other Highlander features
/// that allow equipping items in slots other than the one specified in the Weapon Template,
/// such as using secondary weapons as primaries or equipping them into special sidearm slots.
///
/// To address this issue, this feature introduces a new function: `IsWeaponAllowedByClass_CH()`,
/// which checks whether the weapon is allowed in the inventory slot given to the function as an argument.
///
/// # Compatibility
///
/// For the sake of consistency, it is preferable that mods call `IsWeaponAllowedByClass_CH()` rather than `IsWeaponAllowedByClass()` whenever possible.
final function bool IsWeaponAllowedByClass_CH(X2WeaponTemplate WeaponTemplate, optional EInventorySlot InventorySlot = eInvSlot_Unknown)
{
local SoldierClassWeaponType AllowedWeapon;

if (InventorySlot == eInvSlot_Unknown)
{
return IsWeaponAllowedByClass(WeaponTemplate);
}

switch(InventorySlot)
{
case eInvSlot_PrimaryWeapon: break;
case eInvSlot_SecondaryWeapon: break;
default:
return true;
}

foreach AllowedWeapons(AllowedWeapon)
{
if (AllowedWeapon.WeaponType == WeaponTemplate.WeaponCat && AllowedWeapon.SlotType == InventorySlot)
{
return true;
}
}
return false;
}
// End Issue #1057

function bool IsArmorAllowedByClass(X2ArmorTemplate ArmorTemplate)
{
local int i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8077,7 +8077,7 @@ simulated function bool CanAddItemToInventory(const X2ItemTemplate ItemTemplate,
{
if (IsSoldier() && WeaponTemplate != none)
{
if (!GetSoldierClassTemplate().IsWeaponAllowedByClass(WeaponTemplate))
if (!GetSoldierClassTemplate().IsWeaponAllowedByClass_CH(WeaponTemplate, Slot)) // Issue #1057 - call IsWeaponAllowedByClass_CH() instead of the original.
return false;
}

Expand Down Expand Up @@ -12142,7 +12142,8 @@ function array<X2WeaponTemplate> GetBestPrimaryWeaponTemplates()
WeaponTemplate = X2WeaponTemplate(ItemState.GetMyTemplate());

if (WeaponTemplate != none && WeaponTemplate.bInfiniteItem && (BestWeaponTemplate == none || (BestWeaponTemplates.Find(WeaponTemplate) == INDEX_NONE && WeaponTemplate.Tier >= BestWeaponTemplate.Tier)) &&
WeaponTemplate.InventorySlot == eInvSlot_PrimaryWeapon && GetSoldierClassTemplate().IsWeaponAllowedByClass(WeaponTemplate))
/*WeaponTemplate.InventorySlot == eInvSlot_PrimaryWeapon &&*/ // Issue #1057 - Do not check inventory slot on the template, let IsWeaponAllowedByClass_CH() decide whether the weapon is allowed.
GetSoldierClassTemplate().IsWeaponAllowedByClass_CH(WeaponTemplate, eInvSlot_PrimaryWeapon)) // Issue #1057 - call IsWeaponAllowedByClass_CH() instead of the original.
{
BestWeaponTemplate = WeaponTemplate;
BestWeaponTemplates.AddItem(BestWeaponTemplate);
Expand Down Expand Up @@ -12199,7 +12200,8 @@ function array<X2WeaponTemplate> GetBestSecondaryWeaponTemplates()
WeaponTemplate = X2WeaponTemplate(ItemState.GetMyTemplate());

if(WeaponTemplate != none && WeaponTemplate.bInfiniteItem && (BestWeaponTemplate == none || (BestWeaponTemplates.Find(WeaponTemplate) == INDEX_NONE && WeaponTemplate.Tier >= BestWeaponTemplate.Tier)) &&
WeaponTemplate.InventorySlot == eInvSlot_SecondaryWeapon && GetSoldierClassTemplate().IsWeaponAllowedByClass(WeaponTemplate))
/*WeaponTemplate.InventorySlot == eInvSlot_SecondaryWeapon && */ // Issue #1057 - Do not check inventory slot on the template, let IsWeaponAllowedByClass_CH() decide whether the weapon is allowed.
GetSoldierClassTemplate().IsWeaponAllowedByClass_CH(WeaponTemplate, eInvSlot_SecondaryWeapon)) // Issue #1057 - call IsWeaponAllowedByClass_CH() instead of the original.
{
BestWeaponTemplate = WeaponTemplate;
BestWeaponTemplates.AddItem(BestWeaponTemplate);
Expand Down Expand Up @@ -12248,7 +12250,7 @@ function array<X2WeaponTemplate> GetBestHeavyWeaponTemplates()

if(HeavyWeaponTemplate != none && HeavyWeaponTemplate.bInfiniteItem && (BestHeavyWeaponTemplate == none ||
(BestHeavyWeaponTemplates.Find(HeavyWeaponTemplate) == INDEX_NONE && HeavyWeaponTemplate.Tier >= BestHeavyWeaponTemplate.Tier)) &&
HeavyWeaponTemplate.InventorySlot == eInvSlot_HeavyWeapon && GetSoldierClassTemplate().IsWeaponAllowedByClass(HeavyWeaponTemplate))
HeavyWeaponTemplate.InventorySlot == eInvSlot_HeavyWeapon && GetSoldierClassTemplate().IsWeaponAllowedByClass_CH(HeavyWeaponTemplate, eInvSlot_HeavyWeapon)) // Issue #1057 - call IsWeaponAllowedByClass_CH() instead of the original.
{
BestHeavyWeaponTemplate = HeavyWeaponTemplate;
BestHeavyWeaponTemplates.AddItem(BestHeavyWeaponTemplate);
Expand Down

0 comments on commit ee3ed07

Please sign in to comment.