import class gameuiPersonalLinkSwitcherEvent extends Event { import var isAdvanced : Bool; } import class RPGManager extends IScriptable { public import static function GetItemData( gi : GameInstance, owner : GameObject, itemID : ItemID ) : weak< gameItemData >; public import static function GetInnerItemDataQuality( itemData : InnerItemData ) : gamedataQuality; public import static function GetItemDataQuality( itemData : weak< gameItemData > ) : gamedataQuality; public import static function GetFloatItemQuality( qualityStat : Float ) : gamedataQuality; public import static function IsInnerItemDataIconic( itemData : InnerItemData ) : Bool; public import static function IsItemDataIconic( itemData : weak< gameItemData > ) : Bool; public import static function IsItemBroken( itemData : gameItemData ) : Bool; public import static function ApplyAbilityArray( owner : weak< GameObject >, abilities : array< weak< GameplayAbility_Record > > ); public import static function ShouldFlipNegativeValue( record : weak< Stat_Record > ) : Bool; public import static function ShouldSlotBeAvailable( owner : weak< GameObject >, item : ItemID, attachmentSlotRecord : weak< AttachmentSlot_Record > ) : Bool; public import static function IsSlotAvailable( itemData : weak< gameItemData >, attachmentSlotRecord : weak< AttachmentSlot_Record > ) : Bool; public import static function CalculateStatModifiers( modifiers : array< weak< StatModifier_Record > >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateAdditiveModifiers( modifiers : array< weak< StatModifier_Record > >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateMultiplierModifiers( modifiers : array< weak< StatModifier_Record > >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateAdditiveMultiplierModifiers( modifiers : array< weak< StatModifier_Record > >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateStatModifier( modifier : weak< StatModifier_Record >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateConstantModifier( modifier : weak< ConstantStatModifier_Record > ) : Float; public import static function CalculateRandomModifier( modifier : weak< RandomStatModifier_Record > ) : Float; public import static function CalculateCurveModifier( modifier : weak< CurveStatModifier_Record >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function CalculateCombinedModifier( modifier : weak< CombinedStatModifier_Record >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float; public import static function GetRefObjectID( refObjectName : CName, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : StatsObjectID; public import static function CalculateBuyPrice( context : GameInstance, vendor : weak< GameObject >, itemID : ItemID, multiplier : Float ) : Int32; public import static function CalculateSellPrice( context : GameInstance, vendor : weak< GameObject >, itemID : ItemID ) : Int32; public import static function CalculateSellPriceItemData( context : GameInstance, vendor : weak< GameObject >, itemData : gameItemData ) : Int32; public import static function CalculatePowerDifferential( target : weak< GameObject > ) : gameEPowerDifferential; public static function CalculateStatModifiers( addValue : Float, multValue : Float, addMultValue : Float, const modifiers : ref< array< weak< StatModifier_Record > > >, context : GameInstance, root : weak< GameObject >, targetID : StatsObjectID, optional instigator : StatsObjectID, optional itemStatsID : StatsObjectID ) : Float { var additiveMods : array< weak< StatModifier_Record > >; var multiplierMods : array< weak< StatModifier_Record > >; var addMultMods : array< weak< StatModifier_Record > >; var i : Int32; var modType : CName; for( i = 0; i < modifiers.Size(); i += 1 ) { modType = modifiers[ i ].ModifierType(); switch( modType ) { case 'Additive': additiveMods.PushBack( modifiers[ i ] ); break; case 'Multiplier': multiplierMods.PushBack( modifiers[ i ] ); break; case 'AdditiveMultiplier': addMultMods.PushBack( modifiers[ i ] ); break; default: break; } } addValue += CalculateAdditiveModifiers( additiveMods, context, root, targetID, instigator, itemStatsID ); multValue *= CalculateMultiplierModifiers( multiplierMods, context, root, targetID, instigator, itemStatsID ); addMultValue += CalculateAdditiveMultiplierModifiers( addMultMods, context, root, targetID, instigator, itemStatsID ); return ( addValue * multValue ) * addMultValue; } public static function InjectStatModifier( gi : GameInstance, obj : GameObject, modifier : gameStatModifierData ) { GameInstance.GetStatsSystem( gi ).AddModifier( obj.GetEntityID(), modifier ); } public static function InjectStatModifierToItem( gi : GameInstance, itemData : gameItemData, modifier : gameStatModifierData ) { GameInstance.GetStatsSystem( gi ).AddModifier( itemData.GetStatsObjectID(), modifier ); } public static function IsDamageStat( stat : gamedataStatType ) : Bool { return ( ( ( ( stat == gamedataStatType.PhysicalDamage || stat == gamedataStatType.ThermalDamage ) || stat == gamedataStatType.ChemicalDamage ) || stat == gamedataStatType.ElectricDamage ) || stat == gamedataStatType.DamagePerHit ) || stat == gamedataStatType.EffectiveDamagePerHit; } public static function GetStatValueFromObject( gi : GameInstance, object : weak< GameObject >, stat : gamedataStatType ) : Float { return GameInstance.GetStatsSystem( gi ).GetStatValue( object.GetEntityID(), stat ); } public static function CheckPrereqs( const prereqs : ref< array< weak< IPrereq_Record > > >, target : weak< GameObject >, optional referenceStatsID : StatsObjectID ) : Bool { var i : Int32; var retVal : Bool; retVal = true; for( i = 0; i < prereqs.Size(); i += 1 ) { retVal = retVal && CheckPrereq( prereqs[ i ], target ); if( !( retVal ) ) { break; } } return retVal; } public static function CheckPrereq( prereqRecord : weak< IPrereq_Record >, target : weak< GameObject >, optional referenceStatsID : StatsObjectID ) : Bool { var prereq : IPrereq; var statPrereq : StatPrereq; prereq = IPrereq.CreatePrereq( prereqRecord.GetID() ); statPrereq = ( ( StatPrereq )( prereq ) ); if( statPrereq && StatsObjectID.IsDefined( referenceStatsID ) ) { if( !( statPrereq.IsFulfilled( target.GetGame(), target, referenceStatsID ) ) ) { return false; } } else { if( !( prereq.IsFulfilled( target.GetGame(), target ) ) ) { return false; } } return true; } public static function CheckPerkPrereqs( itemData : gameItemData, owner : GameObject, perkRequiredName : ref< String > ) : Bool { var prereqs : array< weak< IPrereq_Record > >; var perkPrereq : PerkPrereq_Record; var newPerkPrereq : PlayerIsNewPerkBoughtPrereq_Record; var perkType : gamedataPerkType; var newPerkType : gamedataNewPerkType; var perkRecord : Perk_Record; var newPerkRecord : NewPerk_Record; var checkedPerkName : String; var i : Int32; GetItemRecord( itemData.GetID() ).EquipPrereqs( prereqs ); for( i = 0; i < prereqs.Size(); i += 1 ) { perkPrereq = ( ( PerkPrereq_Record )( prereqs[ i ] ) ); if( perkPrereq ) { checkedPerkName = perkPrereq.Perk(); perkRecord = TDB.GetPerkRecord( TDBID.Create( "Perks." + checkedPerkName ) ); if( perkRecord ) { perkType = perkRecord.Type(); if( !( PlayerDevelopmentSystem.GetData( owner ).HasPerk( perkType ) ) ) { perkRequiredName = perkRecord.Loc_name_key(); return true; } } } else { newPerkPrereq = ( ( PlayerIsNewPerkBoughtPrereq_Record )( prereqs[ i ] ) ); if( newPerkPrereq ) { checkedPerkName = newPerkPrereq.PerkType(); newPerkRecord = TDB.GetNewPerkRecord( TDBID.Create( "NewPerks." + checkedPerkName ) ); if( newPerkRecord ) { newPerkType = newPerkRecord.Type(); if( PlayerDevelopmentSystem.GetData( owner ).IsNewPerkBought( newPerkType ) < newPerkPrereq.Level() ) { perkRequiredName = newPerkRecord.Loc_name_key(); return true; } } } } } return false; } public static function GetEquipRequirements( owner : GameObject, itemData : gameItemData ) : array< SItemStackRequirementData > { var i : Int32; var prereqs : array< weak< IPrereq_Record > >; var statPrereqs : array< StatPrereq_Record >; var data : SItemStackRequirementData; var datas : array< SItemStackRequirementData >; var itemRecord : weak< Item_Record >; itemRecord = GetItemRecord( itemData.GetID() ); itemRecord.EquipPrereqs( prereqs ); if( itemRecord.UsesVariants() ) { itemRecord.GetVariantsItem( itemData.GetVariant() ).VariantPrereqs( prereqs ); } statPrereqs = GetNestedPrereqs( prereqs ); for( i = 0; i < statPrereqs.Size(); i += 1 ) { data.statType = ( ( gamedataStatType )( ( ( Int32 )( EnumValueFromName( 'gamedataStatType', statPrereqs[ i ].StatType() ) ) ) ) ); if( statPrereqs[ i ].GetStatModifiersCount() > 0 ) { data.requiredValue = StatsSystemHelper.GetStatPrereqModifiersValue( owner.GetGame(), itemData.GetStatsObjectID(), statPrereqs[ i ].GetID() ); } else { data.requiredValue = statPrereqs[ i ].ValueToCheck(); } datas.PushBack( data ); } return datas; } private static function GetNestedPrereqs( const prereqs : ref< array< weak< IPrereq_Record > > > ) : array< StatPrereq_Record > { var i, j : Int32; var statPrereq : StatPrereq_Record; var multiPrereq : MultiPrereq_Record; var statPrereqs, temps : array< StatPrereq_Record >; var nestedPrereqs : array< weak< IPrereq_Record > >; for( i = 0; i < prereqs.Size(); i += 1 ) { multiPrereq = ( ( MultiPrereq_Record )( prereqs[ i ] ) ); if( multiPrereq ) { nestedPrereqs.Clear(); multiPrereq.NestedPrereqs( nestedPrereqs ); temps = GetNestedPrereqs( nestedPrereqs ); for( j = 0; j < temps.Size(); j += 1 ) { statPrereqs.PushBack( temps[ j ] ); } } else { statPrereq = ( ( StatPrereq_Record )( prereqs[ i ] ) ); if( statPrereq ) { statPrereqs.PushBack( statPrereq ); } } } return statPrereqs; } public static function GetFirstUnmetEquipRequirement( owner : GameObject, const equipRequirements : ref< array< SItemStackRequirementData > > ) : SItemStackRequirementData { var i : Int32; var statsSystem : StatsSystem; var emptyRequirement : SItemStackRequirementData; statsSystem = GameInstance.GetStatsSystem( owner.GetGame() ); for( i = 0; i < equipRequirements.Size(); i += 1 ) { if( statsSystem.GetStatValue( owner.GetEntityID(), equipRequirements[ i ].statType ) < equipRequirements[ i ].requiredValue ) { return equipRequirements[ i ]; } } emptyRequirement.statType = gamedataStatType.Invalid; return emptyRequirement; } public static function GetRarityMultiplier( puppet : weak< NPCPuppet >, curveName : CName ) : Float { var rarity : gamedataNPCRarity; var statsDataSystem : StatsDataSystem; var multiplier : Float; var powerLevel : Float; multiplier = 1.0; rarity = puppet.GetNPCRarity(); statsDataSystem = GameInstance.GetStatsDataSystem( puppet.GetGame() ); powerLevel = GameInstance.GetStatsSystem( puppet.GetGame() ).GetStatValue( puppet.GetEntityID(), gamedataStatType.PowerLevel ); switch( rarity ) { case gamedataNPCRarity.Trash: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_trash_mods', powerLevel, curveName ); break; case gamedataNPCRarity.Weak: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_weak_mods', powerLevel, curveName ); break; case gamedataNPCRarity.Rare: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_rare_mods', powerLevel, curveName ); break; case gamedataNPCRarity.Elite: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_elite_mods', powerLevel, curveName ); break; case gamedataNPCRarity.Officer: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_officer_mods', powerLevel, curveName ); break; case gamedataNPCRarity.Normal: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_normal_mods', powerLevel, curveName ); break; case gamedataNPCRarity.MaxTac: case gamedataNPCRarity.Boss: multiplier = statsDataSystem.GetValueFromCurve( 'puppet_preset_boss_mods', powerLevel, curveName ); break; default: multiplier = 1.0; break; } return multiplier; } public static function ResistancesList() : array< gamedataStatType > { var resistances : array< gamedataStatType >; resistances.PushBack( gamedataStatType.PhysicalResistance ); resistances.PushBack( gamedataStatType.ChemicalResistance ); resistances.PushBack( gamedataStatType.ThermalResistance ); resistances.PushBack( gamedataStatType.ElectricResistance ); return resistances; } public static function ApplyAbility( owner : weak< GameObject >, ability : weak< GameplayAbility_Record > ) { var GLP : GameplayLogicPackageSystem; GLP = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); GLP.RemovePackage( owner, ability.AbilityPackage().GetID() ); GLP.ApplyPackage( owner, owner, ability.AbilityPackage().GetID() ); } public static function RemoveAbility( owner : weak< GameObject >, ability : weak< GameplayAbility_Record > ) { var GLP : GameplayLogicPackageSystem; GLP = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); GLP.RemovePackage( owner, ability.AbilityPackage().GetID() ); } public static function ApplyAbilityGroup( owner : weak< GameObject >, group : weak< GameplayAbilityGroup_Record > ) { var abilities : array< weak< GameplayAbility_Record > >; if( group.GetAbilitiesCount() > 0 ) { group.Abilities( abilities ); RPGManager.ApplyAbilityArray( owner, abilities ); } } public static function RemoveAbilityGroup( owner : weak< GameObject >, group : weak< GameplayAbilityGroup_Record > ) { var i : Int32; var abilities : array< weak< GameplayAbility_Record > >; group.Abilities( abilities ); for( i = 0; i < abilities.Size(); i += 1 ) { RPGManager.RemoveAbility( owner, abilities[ i ] ); } } public static function ApplyGLP( owner : weak< GameObject >, package : weak< GameplayLogicPackage_Record > ) { var appliedPackages : array< TweakDBID >; var glpSys : GameplayLogicPackageSystem; glpSys = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); glpSys.GetAppliedPackages( owner, appliedPackages ); if( !( appliedPackages.Contains( package.GetID() ) ) || package.Stackable() ) { glpSys.ApplyPackage( owner, owner, package.GetID() ); } } public static function RemoveGLP( owner : weak< GameObject >, package : weak< GameplayLogicPackage_Record > ) { var appliedPackages : array< TweakDBID >; var glpSys : GameplayLogicPackageSystem; glpSys = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); glpSys.GetAppliedPackages( owner, appliedPackages ); if( appliedPackages.Contains( package.GetID() ) ) { glpSys.RemovePackage( owner, package.GetID() ); } } public static function ApplyGLPArray( owner : weak< GameObject >, const arr : ref< array< weak< GameplayLogicPackage_Record > > >, optional ignoreAppliedPackages : Bool, optional withAnimationWrapperOverrides : Int32 ) { var i : Int32; var hasAnimWrappers : Bool; var appliedPackages : array< TweakDBID >; var glpSys : GameplayLogicPackageSystem; glpSys = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); if( ignoreAppliedPackages ) { for( i = 0; i < arr.Size(); i += 1 ) { hasAnimWrappers = arr[ i ].GetAnimationWrapperOverridesCount() > 0; if( ( ( withAnimationWrapperOverrides == 0 ) || ( ( withAnimationWrapperOverrides > 0 ) && hasAnimWrappers ) ) || ( ( withAnimationWrapperOverrides < 0 ) && !( hasAnimWrappers ) ) ) { glpSys.ApplyPackage( owner, owner, arr[ i ].GetID() ); } } } else { glpSys.GetAppliedPackages( owner, appliedPackages ); for( i = 0; i < arr.Size(); i += 1 ) { if( arr[ i ].Stackable() || !( appliedPackages.Contains( arr[ i ].GetID() ) ) ) { glpSys.ApplyPackage( owner, owner, arr[ i ].GetID() ); } } } } public static function ApplyEffectorsArray( owner : weak< GameObject >, const arr : ref< array< weak< Effector_Record > > > ) { var i : Int32; var ES : EffectorSystem; ES = GameInstance.GetEffectorSystem( owner.GetGame() ); for( i = 0; i < arr.Size(); i += 1 ) { ES.ApplyEffector( owner.GetEntityID(), owner, arr[ i ].GetID() ); } } public static function RemoveEffectorsArray( owner : weak< GameObject >, const arr : ref< array< weak< Effector_Record > > > ) { var i : Int32; var ES : EffectorSystem; ES = GameInstance.GetEffectorSystem( owner.GetGame() ); for( i = 0; i < arr.Size(); i += 1 ) { ES.RemoveEffector( owner.GetEntityID(), arr[ i ].GetID() ); } } public static function ApplyStatModifierGroups( owner : weak< GameObject >, const arr : ref< array< weak< StatModifierGroup_Record > > > ) { var i : Int32; var modGroupID : Uint64; var SS : StatsSystem; SS = GameInstance.GetStatsSystem( owner.GetGame() ); for( i = 0; i < arr.Size(); i += 1 ) { modGroupID = TDBID.ToNumber( arr[ i ].GetID() ); SS.DefineModifierGroupFromRecord( modGroupID, arr[ i ].GetID() ); SS.ApplyModifierGroup( owner.GetEntityID(), modGroupID ); } } public static function RemoveStatModifierGroups( owner : weak< GameObject >, const arr : ref< array< weak< StatModifierGroup_Record > > > ) { var i : Int32; var modGroupID : Uint64; var SS : StatsSystem; SS = GameInstance.GetStatsSystem( owner.GetGame() ); for( i = 0; i < arr.Size(); i += 1 ) { modGroupID = TDBID.ToNumber( arr[ i ].GetID() ); SS.RemoveModifierGroup( owner.GetEntityID(), modGroupID ); } } public export static function GetLevelPercentage( object : GameObject ) : Int32 { var exp : Int32; exp = PlayerDevelopmentSystem.GetData( object ).GetExperiencePercentage(); return exp; } public static function GetItemQualityFromRecord( itemRecord : Item_Record ) : gamedataQuality { var quality : gamedataQuality; quality = itemRecord.Quality().Type(); if( quality != gamedataQuality.Random ) { return quality; } return gamedataQuality.Invalid; } public static function GetBumpedQuality( quality : gamedataQuality ) : gamedataQuality { switch( quality ) { case gamedataQuality.Common: return gamedataQuality.Uncommon; case gamedataQuality.Uncommon: return gamedataQuality.Rare; case gamedataQuality.Rare: return gamedataQuality.Epic; case gamedataQuality.Epic: return gamedataQuality.Legendary; default: return quality; } } public static function GetItemQuality( itemData : InnerItemData ) : gamedataQuality { return GetItemQuality( InnerItemData.GetStatValueByType( itemData, gamedataStatType.Quality ) ); } public static function ItemQualityNameToValue( q : CName ) : Float { var val : Float; switch( q ) { case 'Common': val = 0.0; break; case 'Uncommon': val = 1.0; break; case 'Rare': val = 2.0; break; case 'Epic': val = 3.0; break; case 'Legendary': val = 4.0; break; default: val = 0.0; break; } return val; } public static function ItemQualityEnumToValue( q : gamedataQuality ) : Float { var val : Float; switch( q ) { case gamedataQuality.Common: val = 0.0; break; case gamedataQuality.Uncommon: val = 1.0; break; case gamedataQuality.Rare: val = 2.0; break; case gamedataQuality.Epic: val = 3.0; break; case gamedataQuality.Legendary: val = 4.0; break; default: val = 0.0; break; } return val; } public static function SetQualityBasedOnLevel( object : weak< GameObject > ) : CName { var playerLevel : Float; var scalingValue : Float; var quality : CName; playerLevel = GameInstance.GetStatsSystem( object.GetGame() ).GetStatValue( object.GetEntityID(), gamedataStatType.Level ); scalingValue = GameInstance.GetStatsDataSystem( object.GetGame() ).GetValueFromCurve( 'quality_curves', playerLevel, 'crafted_iconic_quality_to_level' ); switch( scalingValue ) { case 0.0: quality = 'Common'; break; case 1.0: quality = 'Uncommon'; break; case 2.0: quality = 'Rare'; break; case 3.0: quality = 'Epic'; break; case 4.0: quality = 'Legendary'; break; default: quality = 'Common'; break; } return quality; } public static function GetNextItemQuality( itemData : weak< gameItemData > ) : gamedataQuality { if( itemData ) { return GetItemQuality( itemData.GetStatValueByType( gamedataStatType.Quality ) + 1.0 ); } return gamedataQuality.Invalid; } public static function GetPlayerNextLevelBasedOnRandomQuality( quality : gamedataQuality ) : Int32 { var playerLevel : Int32; switch( quality ) { case gamedataQuality.Uncommon: playerLevel = 9; break; case gamedataQuality.Rare: playerLevel = 17; break; case gamedataQuality.Epic: playerLevel = 25; break; case gamedataQuality.Legendary: playerLevel = 33; break; default: playerLevel = -1; break; } return playerLevel; } public static function GetItemQuality( itemData : weak< gameItemData > ) : gamedataQuality { if( itemData ) { return GetItemQuality( itemData.GetStatValueByType( gamedataStatType.Quality ) ); } return gamedataQuality.Invalid; } public static function GetItemTierForUpgrades( itemData : weak< gameItemData > ) : gamedataQuality { if( itemData ) { return GetItemTierForUpgrades( itemData.GetStatValueByType( gamedataStatType.WasItemUpgraded ) ); } return gamedataQuality.Invalid; } public static function IsItemIconic( itemData : weak< gameItemData > ) : Bool { return itemData.GetStatValueByType( gamedataStatType.IsItemIconic ) > 0.0; } public static function IsItemIconic( itemData : InnerItemData ) : Bool { return InnerItemData.GetStatValueByType( itemData, gamedataStatType.IsItemIconic ) > 0.0; } public static function IsItemMaxLevel( itemData : weak< gameItemData > ) : Bool { var tempStat : Float; tempStat = itemData.GetStatValueByType( gamedataStatType.ItemLevel ); return tempStat >= 500.0; } public static function IsItemMaxTier( itemData : weak< gameItemData > ) : Bool { var tempStat : Float; tempStat = itemData.GetStatValueByType( gamedataStatType.EffectiveTier ); if( IsEP1() ) { return tempStat > 9.98999977; } else { return tempStat > 8.98999977; } } public static function GetItemPlus( itemData : gameItemData ) : Float { if( itemData ) { return itemData.GetStatValueByType( gamedataStatType.IsItemPlus ); } return 0.0; } public static function IsItemWeapon( itemID : ItemID ) : Bool { return RPGManager.GetItemCategory( itemID ) == gamedataItemCategory.Weapon; } public static function IsItemClothing( itemID : ItemID ) : Bool { return RPGManager.GetItemCategory( itemID ) == gamedataItemCategory.Clothing; } public static function IsItemCyberware( itemID : ItemID ) : Bool { return RPGManager.GetItemCategory( itemID ) == gamedataItemCategory.Cyberware; } public static function IsItemGadget( itemID : ItemID ) : Bool { return RPGManager.GetItemCategory( itemID ) == gamedataItemCategory.Gadget; } public static function IsItemProgram( itemID : ItemID ) : Bool { return RPGManager.GetItemType( itemID ) == gamedataItemType.Prt_Program; } public static function IsItemMisc( itemID : ItemID ) : Bool { return RPGManager.GetItemType( itemID ) == gamedataItemType.Gen_Misc; } public static function IsItemTypeCyberwareWeapon( type : gamedataItemType ) : Bool { switch( type ) { case gamedataItemType.Cyb_MantisBlades: case gamedataItemType.Cyb_NanoWires: case gamedataItemType.Cyb_StrongArms: return true; default: return false; } } public static function IsItemAdaptiveStemCells( itemID : TweakDBID ) : Bool { return TweakDBInterface.GetCName( itemID + T".cyberwareType", '' ) == 'AdaptiveStemCells'; } public static function GetItemQuality( qualityStat : Float ) : gamedataQuality { var qualityInt : Int32; qualityInt = RoundF( qualityStat ); switch( qualityInt ) { case 0: return gamedataQuality.Common; case 1: return gamedataQuality.Uncommon; case 2: return gamedataQuality.Rare; case 3: return gamedataQuality.Epic; case 4: return gamedataQuality.Legendary; default: return gamedataQuality.Common; } } public static function GetItemTierForUpgrades( tierStat : Float ) : gamedataQuality { var tierInt : Int32; tierInt = RoundF( tierStat ); switch( tierInt ) { case 0: return gamedataQuality.Common; case 1: return gamedataQuality.CommonPlus; case 2: return gamedataQuality.Uncommon; case 3: return gamedataQuality.UncommonPlus; case 4: return gamedataQuality.Rare; case 5: return gamedataQuality.RarePlus; case 6: return gamedataQuality.Epic; case 7: return gamedataQuality.EpicPlus; case 8: return gamedataQuality.Legendary; case 9: return gamedataQuality.LegendaryPlus; case 10: return gamedataQuality.LegendaryPlusPlus; default: return gamedataQuality.Common; } } public static function GetCraftingMaterialRecord( quality : gamedataQuality, optional isQuickhack : Bool ) : Item_Record { var record : Item_Record; switch( quality ) { case gamedataQuality.Common: record = TweakDBInterface.GetItemRecord( T"Items.CommonMaterial1" ); break; case gamedataQuality.Uncommon: if( isQuickhack ) { record = TweakDBInterface.GetItemRecord( T"Items.QuickHackUncommonMaterial1" ); } else { record = TweakDBInterface.GetItemRecord( T"Items.UncommonMaterial1" ); } break; case gamedataQuality.Rare: if( isQuickhack ) { record = TweakDBInterface.GetItemRecord( T"Items.QuickHackRareMaterial1" ); } else { record = TweakDBInterface.GetItemRecord( T"Items.RareMaterial1" ); } break; case gamedataQuality.Epic: if( isQuickhack ) { record = TweakDBInterface.GetItemRecord( T"Items.QuickHackEpicMaterial1" ); } else { record = TweakDBInterface.GetItemRecord( T"Items.EpicMaterial1" ); } break; case gamedataQuality.Legendary: if( isQuickhack ) { record = TweakDBInterface.GetItemRecord( T"Items.QuickHackLegendaryMaterial1" ); } else { record = TweakDBInterface.GetItemRecord( T"Items.LegendaryMaterial1" ); } break; default: return record; } return record; } public static function GetAvailableSlotsForQuality( itemData : weak< gameItemData >, quality : gamedataQuality ) : Float { switch( quality ) { case gamedataQuality.Common: return 0.0; break; case gamedataQuality.Uncommon: return 0.0; break; case gamedataQuality.Rare: return 1.0; break; case gamedataQuality.Epic: return 2.0; break; case gamedataQuality.Legendary: return 3.0; break; default: return 0.0; } return -1.0; } public static function GetListOfRandomStatsFromEvolutionType( evolution : gamedataWeaponEvolution ) : array< weak< Stat_Record > > { var record : weak< UIStatsMap_Record >; var statMap : array< weak< Stat_Record > >; var tempStr : String; if( evolution == gamedataWeaponEvolution.Invalid ) { record = TweakDBInterface.GetUIStatsMapRecord( T"UIMaps.WeaponGeneral" ); } else { tempStr = "UIMaps."; tempStr += EnumValueToString( "gamedataWeaponEvolution", ( ( Int32 )( evolution ) ) ); record = TweakDBInterface.GetUIStatsMapRecord( TDBID.Create( tempStr ) ); } record.PrimaryStats( statMap ); return statMap; } public static function GetDominatingDamageType( gi : GameInstance, itemData : weak< gameItemData > ) : gamedataDamageType { var i : Int32; var dmgIndex : Int32; var highestValue : Float; var tempStat : Float; var statsSystem : StatsSystem; highestValue = 0.0; statsSystem = GameInstance.GetStatsSystem( gi ); for( i = 0; i < ( ( Int32 )( gamedataDamageType.Count ) ); i += 1 ) { tempStat = statsSystem.GetStatValueFromDamageType( itemData.GetStatsObjectID(), ( ( gamedataDamageType )( i ) ) ); if( tempStat > highestValue ) { highestValue = tempStat; dmgIndex = i; } } return ( ( gamedataDamageType )( dmgIndex ) ); } public static function SetDroppedWeaponQuality( npc : weak< ScriptedPuppet >, itemData : weak< gameItemData > ) { var SS : StatsSystem; var mod : gameStatModifierData; var quality : Float; if( !( npc ) ) { return; } SS = GameInstance.GetStatsSystem( npc.GetGame() ); if( RandF() < 0.89999998 ) { quality = 0.0; } else { quality = 1.0; } SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.Quality, true ); mod = CreateStatModifier( gamedataStatType.Quality, gameStatModifierType.Additive, quality ); SS.AddSavedModifier( itemData.GetStatsObjectID(), mod ); ScriptedPuppet.EvaluateLootQualityByTask( npc ); } public static function ForceItemTier( obj : weak< GameObject >, itemData : weak< gameItemData >, forcedQuality : CName ) { var SS : StatsSystem; var value : Float; var helperMod, qualityMod, plusMod : gameStatModifierData; if( !( obj ) ) { return; } SS = GameInstance.GetStatsSystem( obj.GetGame() ); value = RPGManager.GetItemTierFromName( forcedQuality ); if( ( ( itemData.GetStatValueByType( gamedataStatType.Quality ) * 2.0 ) + itemData.GetStatValueByType( gamedataStatType.IsItemPlus ) ) == value ) { return; } helperMod = CreateStatModifier( gamedataStatType.ForceQualityHelper, gameStatModifierType.Additive, value ); SS.AddSavedModifier( itemData.GetStatsObjectID(), helperMod ); qualityMod = CreateStatModifierUsingCurve( gamedataStatType.Quality, gameStatModifierType.Additive, gamedataStatType.ForceQualityHelper, 'quality_curves', 'iconic_upgrades_amount_to_quality' ); plusMod = CreateStatModifierUsingCurve( gamedataStatType.IsItemPlus, gameStatModifierType.Additive, gamedataStatType.ForceQualityHelper, 'quality_curves', 'iconic_upgrades_amount_to_plus' ); SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.Quality, true ); SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.RandomCurveInput, true ); SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.IsItemPlus, true ); SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.QualityToMaxQualityRatio, true ); SS.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.CommonTierFailsafe, true ); SS.AddSavedModifier( itemData.GetStatsObjectID(), qualityMod ); SS.AddSavedModifier( itemData.GetStatsObjectID(), plusMod ); } public static function ProcessOnLootedPackages( owner : weak< GameObject >, itemID : ItemID ) { var i : Int32; var glp : GameplayLogicPackageSystem; var packages : array< weak< GameplayLogicPackage_Record > >; RPGManager.GetItemRecord( itemID ).OnLooted( packages ); glp = GameInstance.GetGameplayLogicPackageSystem( owner.GetGame() ); for( i = 0; i < packages.Size(); i += 1 ) { glp.ApplyPackage( owner, owner, packages[ i ].GetID() ); } } public constexpr static function GetItemTierFromName( tierName : CName ) : Float { switch( tierName ) { case 'Common': return 0.0; case 'CommonPlus': return 1.0; case 'Uncommon': return 2.0; case 'UncommonPlus': return 3.0; case 'Rare': return 4.0; case 'RarePlus': return 5.0; case 'Epic': return 6.0; case 'EpicPlus': return 7.0; case 'Legendary': return 8.0; case 'LegendaryPlus': return 9.0; case 'LegendaryPlusPlus': return 10.0; default: return 0.0; } } public static function GetCombinedItemQualityValue( game : GameInstance, itemID : ItemID ) : Int32 { var statsSystem : StatsSystem; var statsID : StatsObjectID; statsSystem = GameInstance.GetStatsSystem( game ); statsID = ( ( StatsObjectID )( itemID ) ); if( statsSystem && StatsObjectID.IsDefined( statsID ) ) { return ( ( Int32 )( ( statsSystem.GetStatValue( statsID, gamedataStatType.Quality ) * 2.0 ) + statsSystem.GetStatValue( statsID, gamedataStatType.IsItemPlus ) ) ); } return 0; } public constexpr static function ConvertQualityToNonPlusQuality( quality : gamedataQuality ) : gamedataQuality { switch( quality ) { case gamedataQuality.Common: case gamedataQuality.CommonPlus: return gamedataQuality.Common; case gamedataQuality.Uncommon: case gamedataQuality.UncommonPlus: return gamedataQuality.Uncommon; case gamedataQuality.Rare: case gamedataQuality.RarePlus: return gamedataQuality.Rare; case gamedataQuality.Epic: case gamedataQuality.EpicPlus: return gamedataQuality.Epic; case gamedataQuality.Legendary: case gamedataQuality.LegendaryPlus: case gamedataQuality.LegendaryPlusPlus: return gamedataQuality.Legendary; default: return gamedataQuality.Invalid; } } public constexpr static function ConvertQualityToItemPlusValue( quality : gamedataQuality ) : Int32 { switch( quality ) { case gamedataQuality.LegendaryPlusPlus: return 2; case gamedataQuality.CommonPlus: case gamedataQuality.UncommonPlus: case gamedataQuality.RarePlus: case gamedataQuality.EpicPlus: case gamedataQuality.LegendaryPlus: return 1; default: return 0; } } public constexpr static function ConvertCombinedValueToQuality( combinedValue : Int32 ) : gamedataQuality { switch( combinedValue ) { case 0: return gamedataQuality.Common; case 1: return gamedataQuality.CommonPlus; case 2: return gamedataQuality.Uncommon; case 3: return gamedataQuality.UncommonPlus; case 4: return gamedataQuality.Rare; case 5: return gamedataQuality.RarePlus; case 6: return gamedataQuality.Epic; case 7: return gamedataQuality.EpicPlus; case 8: return gamedataQuality.Legendary; case 9: return gamedataQuality.LegendaryPlus; case 10: return gamedataQuality.LegendaryPlusPlus; default: return gamedataQuality.Invalid; } } public constexpr static function ConvertQualityToCombinedValue( quality : gamedataQuality ) : Int32 { switch( quality ) { case gamedataQuality.Common: return 0; case gamedataQuality.CommonPlus: return 1; case gamedataQuality.Uncommon: return 2; case gamedataQuality.UncommonPlus: return 3; case gamedataQuality.Rare: return 4; case gamedataQuality.RarePlus: return 5; case gamedataQuality.Epic: return 6; case gamedataQuality.EpicPlus: return 7; case gamedataQuality.Legendary: return 8; case gamedataQuality.LegendaryPlus: return 9; case gamedataQuality.LegendaryPlusPlus: return 10; default: return 0; } } public constexpr static function ConvertPlayerLevelToCyberwareQuality( playerLevel : Float, includeAboveLegendary : Bool ) : gamedataQuality { if( includeAboveLegendary && ( playerLevel > 50.0 ) ) { return gamedataQuality.LegendaryPlusPlus; } if( includeAboveLegendary && ( playerLevel > 46.0 ) ) { return gamedataQuality.LegendaryPlus; } if( playerLevel > 39.0 ) { return gamedataQuality.Legendary; } if( playerLevel > 36.0 ) { return gamedataQuality.EpicPlus; } if( playerLevel > 29.0 ) { return gamedataQuality.Epic; } if( playerLevel > 26.0 ) { return gamedataQuality.RarePlus; } if( playerLevel > 19.0 ) { return gamedataQuality.Rare; } if( playerLevel > 16.0 ) { return gamedataQuality.UncommonPlus; } if( playerLevel > 9.0 ) { return gamedataQuality.Uncommon; } if( playerLevel > 6.0 ) { return gamedataQuality.CommonPlus; } return gamedataQuality.Common; } public static function HasItem( obj : weak< GameObject >, id : TweakDBID ) : Bool { var itemID : ItemID; itemID = ItemID.CreateQuery( id ); return GameInstance.GetTransactionSystem( obj.GetGame() ).HasItem( obj, itemID ); } public static function HasItem( obj : weak< GameObject >, id : ItemID ) : Bool { return GameInstance.GetTransactionSystem( obj.GetGame() ).HasItem( obj, id ); } public static function GetItemType( itemID : ItemID ) : gamedataItemType { if( ItemID.IsValid( itemID ) ) { return TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ).ItemType().Type(); } return gamedataItemType.Invalid; } public static function IsClothingMod( itemID : ItemID ) : Bool { if( ItemID.IsValid( itemID ) ) { return IsClothingMod( RPGManager.GetItemType( itemID ) ); } else { return false; } } public static function IsClothingMod( type : gamedataItemType ) : Bool { switch( type ) { case gamedataItemType.Prt_FabricEnhancer: return true; case gamedataItemType.Prt_HeadFabricEnhancer: return true; case gamedataItemType.Prt_FaceFabricEnhancer: return true; case gamedataItemType.Prt_TorsoFabricEnhancer: return true; case gamedataItemType.Prt_OuterTorsoFabricEnhancer: return true; case gamedataItemType.Prt_PantsFabricEnhancer: return true; case gamedataItemType.Prt_BootsFabricEnhancer: return true; default: return false; } } public static function IsWeaponMod( itemID : ItemID ) : Bool { if( ItemID.IsValid( itemID ) ) { return IsWeaponMod( RPGManager.GetItemType( itemID ) ); } else { return false; } } public static function IsWeaponMod( type : gamedataItemType ) : Bool { switch( type ) { case gamedataItemType.Prt_Mod: return true; case gamedataItemType.Prt_RangedMod: return true; case gamedataItemType.Prt_PowerMod: return true; case gamedataItemType.Prt_TechMod: return true; case gamedataItemType.Prt_SmartMod: return true; case gamedataItemType.Prt_AR_SMG_LMGMod: return true; case gamedataItemType.Prt_HandgunMod: return true; case gamedataItemType.Prt_Precision_Sniper_RifleMod: return true; case gamedataItemType.Prt_ShotgunMod: return true; case gamedataItemType.Prt_MeleeMod: return true; case gamedataItemType.Prt_BladeMod: return true; case gamedataItemType.Prt_BluntMod: return true; case gamedataItemType.Prt_ThrowableMod: return true; default: return false; } } public static function IsScopeAttachment( itemID : ItemID ) : Bool { if( ItemID.IsValid( itemID ) ) { return IsScopeAttachment( RPGManager.GetItemType( itemID ) ); } else { return false; } } public static function IsScopeAttachment( type : gamedataItemType ) : Bool { switch( type ) { case gamedataItemType.Prt_Scope: return true; case gamedataItemType.Prt_ShortScope: return true; case gamedataItemType.Prt_LongScope: return true; case gamedataItemType.Prt_TechSniperScope: return true; case gamedataItemType.Prt_PowerSniperScope: return true; default: return false; } } public static function IsMuzzleAttachment( type : gamedataItemType ) : Bool { switch( type ) { case gamedataItemType.Prt_Muzzle: return true; case gamedataItemType.Prt_RifleMuzzle: return true; case gamedataItemType.Prt_HandgunMuzzle: return true; default: return false; } } public static function ReturnRetrievableWeaponMods( itemData : weak< gameItemData >, owner : weak< GameObject > ) { var restoredAttachments : array< ItemAttachments >; var transactionSystem : TransactionSystem; var removedID : ItemID; var i : Int32; if( !( itemData ) || !( owner ) ) { return; } restoredAttachments = GetRetrievableAttachments( itemData ); transactionSystem = GameInstance.GetTransactionSystem( owner.GetGame() ); for( i = 0; i < restoredAttachments.Size(); i += 1 ) { removedID = transactionSystem.RemovePart( owner, itemData.GetID(), restoredAttachments[ i ].attachmentSlotID ); if( ItemID.IsValid( removedID ) ) { transactionSystem.GiveItem( owner, restoredAttachments[ i ].itemID, 1 ); } } } public static function GetRetrievableAttachments( itemData : weak< gameItemData > ) : array< ItemAttachments > { var restoredAttachments : array< ItemAttachments >; var slotsToCheck : array< TweakDBID >; var tempArr : array< TweakDBID >; var innerPartID : ItemID; var partTags : array< CName >; var innerPart : InnerItemData; var i : Int32; if( !( itemData ) ) { return restoredAttachments; } if( RPGManager.GetItemCategory( itemData.GetID() ) == gamedataItemCategory.Weapon ) { slotsToCheck = RPGManager.GetAttachmentSlotIDs(); tempArr = RPGManager.GetModsSlotIDs( itemData.GetItemType() ); for( i = 0; i < tempArr.Size(); i += 1 ) { slotsToCheck.PushBack( tempArr[ i ] ); } for( i = 0; i < slotsToCheck.Size(); i += 1 ) { itemData.GetItemPart( innerPart, slotsToCheck[ i ] ); innerPartID = InnerItemData.GetItemID( innerPart ); partTags = InnerItemData.GetStaticData( innerPart ).Tags(); if( ItemID.IsValid( innerPartID ) && partTags.Contains( 'Retrievable' ) ) { restoredAttachments.PushBack( ItemAttachments.Create( innerPartID, slotsToCheck[ i ] ) ); } } } return restoredAttachments; } public static function GetItemCategory( itemID : ItemID ) : gamedataItemCategory { var itemRecord : Item_Record; var itemCategory : weak< ItemCategory_Record >; if( ItemID.IsValid( itemID ) ) { itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ); if( itemRecord ) { itemCategory = itemRecord.ItemCategory(); if( itemCategory ) { return itemCategory.Type(); } } } return gamedataItemCategory.Invalid; } public static function GetWeaponEvolution( itemID : ItemID ) : gamedataWeaponEvolution { var itemRecord : WeaponItem_Record; var weaponEvolution : weak< WeaponEvolution_Record >; if( ItemID.IsValid( itemID ) ) { itemRecord = TweakDBInterface.GetWeaponItemRecord( ItemID.GetTDBID( itemID ) ); if( itemRecord ) { weaponEvolution = itemRecord.Evolution(); if( weaponEvolution ) { return weaponEvolution.Type(); } } } return gamedataWeaponEvolution.Invalid; } public static function GetItemWeight( itemData : gameItemData ) : Float { if( itemData ) { return itemData.GetStatValueByType( gamedataStatType.Weight ); } return 0.0; } public static function GetItemStackWeight( owner : weak< GameObject >, itemData : weak< gameItemData > ) : Float { var quantity : Float; var weight : Float; quantity = ( ( Float )( GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemQuantity( owner, itemData.GetID() ) ) ); weight = GetItemWeight( itemData ); return quantity * weight; } public static function IsItemSingleInstance( itemData : weak< gameItemData > ) : Bool { return GetItemRecord( itemData.GetID() ).IsSingleInstance(); } public static function GetItemFromInventory( object : GameObject, item : TweakDBID ) : ItemID { var i : Int32; var items : array< weak< gameItemData > >; var TS : TransactionSystem; TS = GameInstance.GetTransactionSystem( object.GetGame() ); TS.GetItemList( object, items ); for( i = i; i < items.Size(); i += 1 ) { if( ItemID.GetTDBID( items[ i ].GetID() ) == item ) { return items[ i ].GetID(); } } return ItemID.None(); } public static function GetAttachmentSlotIDs() : array< TweakDBID > { var arr : array< TweakDBID >; arr.PushBack( T"AttachmentSlots.Scope" ); arr.PushBack( T"AttachmentSlots.ScopeRail" ); arr.PushBack( T"AttachmentSlots.PowerModule" ); return arr; } public static function GetModsSlotIDs( type : gamedataItemType ) : array< TweakDBID > { var arr : array< TweakDBID >; switch( type ) { case gamedataItemType.Clo_Head: arr.PushBack( T"AttachmentSlots.HeadFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.HeadFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.HeadFabricEnhancer3" ); arr.PushBack( T"AttachmentSlots.HeadFabricEnhancer4" ); break; case gamedataItemType.Clo_Feet: arr.PushBack( T"AttachmentSlots.FootFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.FootFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.FootFabricEnhancer3" ); arr.PushBack( T"AttachmentSlots.FootFabricEnhancer4" ); break; case gamedataItemType.Clo_Face: arr.PushBack( T"AttachmentSlots.FaceFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.FaceFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.FaceFabricEnhancer3" ); arr.PushBack( T"AttachmentSlots.FaceFabricEnhancer4" ); break; case gamedataItemType.Clo_InnerChest: arr.PushBack( T"AttachmentSlots.InnerChestFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.InnerChestFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.InnerChestFabricEnhancer3" ); break; case gamedataItemType.Clo_Legs: arr.PushBack( T"AttachmentSlots.LegsFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.LegsFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.LegsFabricEnhancer3" ); arr.PushBack( T"AttachmentSlots.LegsFabricEnhancer4" ); break; case gamedataItemType.Clo_OuterChest: arr.PushBack( T"AttachmentSlots.OuterChestFabricEnhancer1" ); arr.PushBack( T"AttachmentSlots.OuterChestFabricEnhancer2" ); arr.PushBack( T"AttachmentSlots.OuterChestFabricEnhancer3" ); break; case gamedataItemType.Wea_AssaultRifle: case gamedataItemType.Wea_Rifle: case gamedataItemType.Wea_SubmachineGun: case gamedataItemType.Wea_LightMachineGun: arr.PushBack( T"AttachmentSlots.Power_AR_SMG_LMG_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Power_AR_SMG_LMG_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Power_AR_SMG_LMG_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Power_AR_SMG_LMG_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.Tech_AR_SMG_LMG_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Tech_AR_SMG_LMG_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Smart_AR_SMG_LMG_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Smart_AR_SMG_LMG_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod1" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod3" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod4" ); return arr; case gamedataItemType.Wea_Handgun: case gamedataItemType.Wea_Revolver: arr.PushBack( T"AttachmentSlots.Power_Handgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Power_Handgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Power_Handgun_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Power_Handgun_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.Tech_Handgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Tech_Handgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Smart_Handgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Smart_Handgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Smart_Handgun_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Smart_Handgun_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod1" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod3" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod4" ); return arr; case gamedataItemType.Wea_PrecisionRifle: case gamedataItemType.Wea_SniperRifle: arr.PushBack( T"AttachmentSlots.Power_Precision_Sniper_Rifle_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Power_Precision_Sniper_Rifle_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Tech_Precision_Sniper_Rifle_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Tech_Precision_Sniper_Rifle_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Tech_Precision_Sniper_Rifle_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Tech_Precision_Sniper_Rifle_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.Smart_Precision_Sniper_Rifle_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Smart_Precision_Sniper_Rifle_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Smart_Precision_Sniper_Rifle_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Smart_Precision_Sniper_Rifle_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod1" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod3" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod4" ); return arr; case gamedataItemType.Wea_Shotgun: case gamedataItemType.Wea_ShotgunDual: arr.PushBack( T"AttachmentSlots.Power_Shotgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Power_Shotgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Power_Shotgun_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Power_Shotgun_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.Tech_Shotgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Tech_Shotgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Smart_Shotgun_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Smart_Shotgun_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod1" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod2" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod3" ); arr.PushBack( T"AttachmentSlots.GenericWeaponMod4" ); return arr; case gamedataItemType.Wea_Chainsword: case gamedataItemType.Wea_Katana: case gamedataItemType.Wea_Sword: case gamedataItemType.Wea_LongBlade: case gamedataItemType.Wea_Machete: case gamedataItemType.Wea_ShortBlade: arr.PushBack( T"AttachmentSlots.Blade_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Blade_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Blade_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Blade_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod1" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod2" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod3" ); return arr; case gamedataItemType.Wea_Axe: case gamedataItemType.Wea_Knife: arr.PushBack( T"AttachmentSlots.Throwable_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Throwable_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Throwable_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Throwable_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod1" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod2" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod3" ); return arr; case gamedataItemType.Wea_Hammer: case gamedataItemType.Wea_OneHandedClub: case gamedataItemType.Wea_TwoHandedClub: arr.PushBack( T"AttachmentSlots.Blunt_WeaponMod1" ); arr.PushBack( T"AttachmentSlots.Blunt_WeaponMod2" ); arr.PushBack( T"AttachmentSlots.Blunt_WeaponMod1_Collectible" ); arr.PushBack( T"AttachmentSlots.Blunt_WeaponMod2_Collectible" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod1" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod2" ); arr.PushBack( T"AttachmentSlots.MeleeWeaponMod3" ); return arr; } return arr; } public static function IsInventoryEmpty( object : weak< GameObject > ) : Bool { var items : array< weak< gameItemData > >; GameInstance.GetTransactionSystem( object.GetGame() ).GetItemList( object, items ); return items.Size() <= 0; } public static function ProcessReadAction( choice : InteractionChoiceEvent ) { var lootActionWrapper : LootChoiceActionWrapper; lootActionWrapper = LootChoiceActionWrapper.Unwrap( choice ); if( LootChoiceActionWrapper.IsValid( lootActionWrapper ) ) { if( lootActionWrapper.action == 'Read' ) { ItemActionsHelper.ReadItem( choice.activator, lootActionWrapper.itemId ); } } } public static function ToggleLootHighlight( obj : weak< GameObject >, enable : Bool ) { var recordID : TweakDBID; recordID = T"Effectors.LootHighlightEffector"; if( enable ) { GameInstance.GetEffectorSystem( obj.GetGame() ).ApplyEffector( obj.GetEntityID(), obj, recordID ); } else { GameInstance.GetEffectorSystem( obj.GetGame() ).RemoveEffector( obj.GetEntityID(), recordID ); } } public static function CreateStatModifier( statType : gamedataStatType, modType : gameStatModifierType, value : Float ) : gameStatModifierData { var newMod : gameConstantStatModifierData; newMod = new gameConstantStatModifierData; newMod.statType = statType; newMod.modifierType = modType; newMod.value = value; return newMod; } public static function CreateStatModifierUsingCurve( statType : gamedataStatType, modType : gameStatModifierType, refStat : gamedataStatType, curveName : CName, columnName : CName ) : gameStatModifierData { var newMod : gameCurveStatModifierData; newMod = new gameCurveStatModifierData; newMod.statType = statType; newMod.curveStat = refStat; newMod.modifierType = modType; newMod.curveName = curveName; newMod.columnName = columnName; return newMod; } public static function CreateCombinedStatModifier( statType : gamedataStatType, modType : gameStatModifierType, refStat : gamedataStatType, opSymbol : gameCombinedStatOperation, value : Float, refObject : gameStatObjectsRelation ) : gameStatModifierData { var newMod : gameCombinedStatModifierData; newMod = new gameCombinedStatModifierData; newMod.statType = statType; newMod.modifierType = modType; newMod.value = value; newMod.refStatType = refStat; newMod.operation = opSymbol; newMod.refObject = refObject; return newMod; } public static function CreateCurveModifier( statRecord : CurveStatModifier_Record ) : gameStatModifierData { var newMod : gameCurveStatModifierData; newMod = new gameCurveStatModifierData; newMod.statType = statRecord.StatType().StatType(); newMod.modifierType = ( ( gameStatModifierType )( ( ( Int32 )( EnumValueFromName( 'gameStatModifierType', statRecord.ModifierType() ) ) ) ) ); newMod.curveName = StringToName( statRecord.Id() ); newMod.columnName = StringToName( statRecord.Column() ); newMod.curveStat = statRecord.RefStat().StatType(); return newMod; } public static function StatRecordToModifier( statRecord : StatModifier_Record ) : gameStatModifierData { var statType : gamedataStatType; var modType : gameStatModifierType; var combinedOp : gameCombinedStatOperation; var relation : gameStatObjectsRelation; var value : Float; var curveMod : CurveStatModifier_Record; var constMod : ConstantStatModifier_Record; var combinedMod : CombinedStatModifier_Record; constMod = ( ( ConstantStatModifier_Record )( statRecord ) ); curveMod = ( ( CurveStatModifier_Record )( statRecord ) ); combinedMod = ( ( CombinedStatModifier_Record )( statRecord ) ); if( constMod ) { statType = constMod.StatType().StatType(); modType = ( ( gameStatModifierType )( ( ( Int32 )( EnumValueFromName( 'gameStatModifierType', constMod.ModifierType() ) ) ) ) ); value = constMod.Value(); return CreateStatModifier( statType, modType, value ); } else if( curveMod ) { return CreateCurveModifier( curveMod ); } else if( combinedMod ) { statType = combinedMod.StatType().StatType(); modType = ( ( gameStatModifierType )( ( ( Int32 )( EnumValueFromName( 'gameStatModifierType', combinedMod.ModifierType() ) ) ) ) ); combinedOp = ( ( gameCombinedStatOperation )( ( ( Int32 )( EnumValueFromName( 'gameCombinedStatOperation', combinedMod.OpSymbol() ) ) ) ) ); relation = ( ( gameStatObjectsRelation )( ( ( Int32 )( EnumValueFromName( 'gameStatObjectsRelation', combinedMod.RefObject() ) ) ) ) ); value = constMod.Value(); return CreateCombinedStatModifier( statType, modType, combinedMod.RefStatHandle().StatType(), combinedOp, value, relation ); } else { return CreateStatModifier( gamedataStatType.Quantity, gameStatModifierType.Additive, 0.0 ); } } public static function GetPowerLevelFromContentAssignment( gi : GameInstance, contentAssignmentID : TweakDBID ) : Float { var constantModRecord : weak< ConstantStatModifier_Record >; var curveModRecord : weak< CurveStatModifier_Record >; var contentAssignment : weak< ContentAssignment_Record >; contentAssignment = TweakDBInterface.GetContentAssignmentRecord( contentAssignmentID ); if( contentAssignment ) { constantModRecord = ( ( ConstantStatModifier_Record )( contentAssignment.PowerLevelMod() ) ); curveModRecord = ( ( CurveStatModifier_Record )( contentAssignment.PowerLevelMod() ) ); if( constantModRecord ) { return constantModRecord.Value(); } else if( curveModRecord ) { return GameInstance.GetStatsDataSystem( gi ).GetMinValueFromCurve( StringToName( curveModRecord.Id() ), StringToName( curveModRecord.Column() ) ); } else { return ( ( Float )( GameInstance.GetLevelAssignmentSystem( gi ).GetLevelAssignment( contentAssignment.GetID() ) ) ); } } return 0.0; } public static function CheckDifficultyToStatValue( gi : GameInstance, skill : gamedataStatType, difficulty : EGameplayChallengeLevel, id : EntityID ) : Int32 { var checkPowerLevel : Float; var entity : weak< Entity >; var device : weak< Device >; var vehicle : weak< VehicleObject >; entity = GameInstance.FindEntityByID( gi, id ); device = ( ( Device )( entity ) ); vehicle = ( ( VehicleObject )( entity ) ); if( device ) { checkPowerLevel = RPGManager.GetPowerLevelFromContentAssignment( gi, device.GetContentScale() ); } if( vehicle ) { checkPowerLevel = RPGManager.GetStatValueFromObject( gi, vehicle, gamedataStatType.PowerLevel ); } return RPGManager.GetCheckValue( gi, checkPowerLevel, difficulty ); } public static function GetCheckValue( gi : GameInstance, powerLevel : Float, difficulty : EGameplayChallengeLevel ) : Int32 { var curveName : CName; switch( difficulty ) { case EGameplayChallengeLevel.NONE: curveName = 'none_difficulty'; break; case EGameplayChallengeLevel.EASY: curveName = 'easy_difficulty'; break; case EGameplayChallengeLevel.MEDIUM: curveName = 'medium_difficulty'; break; case EGameplayChallengeLevel.HARD: curveName = 'hard_difficulty'; break; case EGameplayChallengeLevel.IMPOSSIBLE: curveName = 'impossible_difficulty'; break; } return RoundMath( GameInstance.GetStatsDataSystem( gi ).GetValueFromCurve( 'attribute_checks', powerLevel, curveName ) ); } public static function CheckDifficultyToPerkLevel( perk : gamedataPerkType, difficulty : EGameplayChallengeLevel, id : EntityID ) : Int32 { return ( ( Int32 )( difficulty ) ); } public static function GetBuildScore( player : GameObject, buildToCheck : PlayerBuild_Record ) : Int32 { var attribute : gamedataStatType; var attributeBonus : gamedataStatType; var buildType : gamedataPlayerBuild; var statsSystem : StatsSystem; var attributeBaseValue : Int32; var attributeBonusValue : Int32; var maxValue : Int32; attributeBonus = gamedataStatType.Invalid; attributeBaseValue = 0; attributeBonusValue = 0; maxValue = 20; buildType = buildToCheck.Type(); statsSystem = GameInstance.GetStatsSystem( player.GetGame() ); switch( buildType ) { case gamedataPlayerBuild.Netrunner: attribute = gamedataStatType.Intelligence; attributeBonus = gamedataStatType.IntelligenceSkillcheckBonus; break; case gamedataPlayerBuild.Solo: attribute = gamedataStatType.Strength; attributeBonus = gamedataStatType.StrengthSkillcheckBonus; break; case gamedataPlayerBuild.Techie: attribute = gamedataStatType.TechnicalAbility; attributeBonus = gamedataStatType.TechnicalAbilitySkillcheckBonus; break; case gamedataPlayerBuild.Reflexes: attribute = gamedataStatType.Reflexes; break; case gamedataPlayerBuild.Cool: attribute = gamedataStatType.Cool; break; } attributeBaseValue = ( ( Int32 )( statsSystem.GetStatValue( player.GetEntityID(), attribute ) ) ); if( attributeBonus != gamedataStatType.Invalid ) { attributeBonusValue = ( ( Int32 )( statsSystem.GetStatValue( player.GetEntityID(), attributeBonus ) ) ); } return Min( attributeBaseValue + attributeBonusValue, maxValue ); } public static function GetBluelineBuildCheckValue( player : GameObject, contentAssignment : ContentAssignment_Record, difficulty : EGameplayChallengeLevel ) : Int32 { var checkPowerLevel : Float; checkPowerLevel = RPGManager.GetPowerLevelFromContentAssignment( player.GetGame(), contentAssignment.GetID() ); return RPGManager.GetCheckValue( player.GetGame(), checkPowerLevel, difficulty ); } public static function GetBluelinePaymentValue( player : GameObject, contentAssignment : ContentAssignment_Record, difficulty : EGameplayChallengeLevel ) : Int32 { var paymentPowerLevel : Float; var scaledPaymentValue : Float; var playerMoney : Int32; var base : Float; var quotient : Float; var digitCount : Int32; var overrideValue : Int32; var upToAmountCheck : Bool; paymentPowerLevel = RPGManager.GetPowerLevelFromContentAssignment( player.GetGame(), contentAssignment.GetID() ); scaledPaymentValue = GameInstance.GetStatsDataSystem( player.GetGame() ).GetValueFromCurve( 'price_curves', paymentPowerLevel, 'power_level_to_payment_check' ); switch( difficulty ) { case EGameplayChallengeLevel.NONE: scaledPaymentValue = 1.0; break; case EGameplayChallengeLevel.EASY: scaledPaymentValue *= 0.25; break; case EGameplayChallengeLevel.HARD: scaledPaymentValue *= 2.0; break; case EGameplayChallengeLevel.IMPOSSIBLE: scaledPaymentValue *= 10.0; break; default: break; } quotient = scaledPaymentValue; while( ( quotient > 1.0 ) && ( digitCount < 10 ) ) { digitCount += 1; base = PowF( 10.0, ( ( Float )( digitCount ) ) ); quotient = scaledPaymentValue / base; } base = PowF( 10.0, ( ( Float )( CeilF( ( ( Float )( digitCount ) ) / 2.0 ) ) ) ); scaledPaymentValue /= base; scaledPaymentValue = ( ( Float )( RoundMath( scaledPaymentValue ) ) ); scaledPaymentValue *= base; overrideValue = TweakDBInterface.GetInt( contentAssignment.GetID() + T".overrideValue", 0 ); if( overrideValue > 0 ) { scaledPaymentValue = ( ( Float )( overrideValue ) ); } upToAmountCheck = TweakDBInterface.GetBool( contentAssignment.GetID() + T".upToCheck", false ); if( upToAmountCheck ) { playerMoney = GameInstance.GetTransactionSystem( player.GetGame() ).GetItemQuantity( player, MarketSystem.Money() ); if( playerMoney < ( ( Int32 )( scaledPaymentValue ) ) ) { scaledPaymentValue = ( ( Float )( playerMoney ) ); } } return RoundF( scaledPaymentValue ); } public static function GetStatRecord( type : gamedataStatType ) : Stat_Record { return TweakDBInterface.GetStatRecord( TDBID.Create( "BaseStats." + EnumValueToString( "gamedataStatType", ( ( Int32 )( type ) ) ) ) ); } public static function GetProficiencyRecord( type : gamedataProficiencyType ) : Proficiency_Record { return TweakDBInterface.GetProficiencyRecord( TDBID.Create( "Proficiencies." + EnumValueToString( "gamedataProficiencyType", ( ( Int32 )( type ) ) ) ) ); } public static function GetTraitRecord( type : gamedataTraitType ) : Trait_Record { return TweakDBInterface.GetTraitRecord( TDBID.Create( "Traits." + EnumValueToString( "gamedataTraitType", ( ( Int32 )( type ) ) ) ) ); } public static function GetAttributeDataRecord( type : gamedataAttributeDataType ) : AttributeData_Record { return TweakDBInterface.GetAttributeDataRecord( TDBID.Create( "NewPerks." + EnumValueToString( "gamedataAttributeDataType", ( ( Int32 )( type ) ) ) ) ); } public static function GetNewPerkRecord( type : gamedataNewPerkType ) : NewPerk_Record { return TweakDBInterface.GetNewPerkRecord( TDBID.Create( "NewPerks." + EnumValueToString( "gamedataNewPerkType", ( ( Int32 )( type ) ) ) ) ); } public static function GetResistanceTypeFromDamageType( damageType : gamedataDamageType ) : gamedataStatType { switch( damageType ) { case gamedataDamageType.Physical: return gamedataStatType.PhysicalResistance; case gamedataDamageType.Thermal: return gamedataStatType.ThermalResistance; case gamedataDamageType.Chemical: return gamedataStatType.ChemicalResistance; case gamedataDamageType.Electric: return gamedataStatType.ElectricResistance; default: return gamedataStatType.Invalid; } } public static function CalculatePowerDifferential( level : Int32 ) : gameEPowerDifferential { if( level <= ( ( Int32 )( gameEPowerDifferential.IMPOSSIBLE ) ) ) { return gameEPowerDifferential.IMPOSSIBLE; } else if( ( level > ( ( Int32 )( gameEPowerDifferential.IMPOSSIBLE ) ) ) && ( level <= ( ( Int32 )( gameEPowerDifferential.HARD ) ) ) ) { return gameEPowerDifferential.HARD; } else if( ( level > ( ( Int32 )( gameEPowerDifferential.HARD ) ) ) && ( level <= ( ( Int32 )( gameEPowerDifferential.NORMAL ) ) ) ) { return gameEPowerDifferential.NORMAL; } else if( ( level > ( ( Int32 )( gameEPowerDifferential.NORMAL ) ) ) && ( level <= ( ( Int32 )( gameEPowerDifferential.EASY ) ) ) ) { return gameEPowerDifferential.EASY; } else { return gameEPowerDifferential.TRASH; } } public static function CalculateThreatValue( obj : GameObject ) : Float { var threatVal : Float; var statsSystem : StatsSystem; var player : StatsObjectID; var npc : StatsObjectID; var npcPowerLevel : Float; var playerPowerLevel : Float; var normPowerLevelDiff : Float; var maxPowerLevel : Float; var minPowerLevel : Float; statsSystem = GameInstance.GetStatsSystem( obj.GetGame() ); player = GetPlayer( obj.GetGame() ).GetEntityID(); npc = obj.GetEntityID(); threatVal = 0.0; maxPowerLevel = 60.0; minPowerLevel = 0.0; npcPowerLevel = statsSystem.GetStatValue( npc, gamedataStatType.PowerLevel ); playerPowerLevel = statsSystem.GetStatValue( player, gamedataStatType.PowerLevel ); normPowerLevelDiff = MathHelper.NormalizeF( npcPowerLevel - playerPowerLevel, maxPowerLevel - minPowerLevel, minPowerLevel - maxPowerLevel ); threatVal = normPowerLevelDiff; return threatVal; } public static function GetScannerResistanceDetails( obj : GameObject, statType : gamedataStatType, optional player : GameObject ) : ScannerStatDetails { var currentResist : Float; var statsSystem : StatsSystem; var scanStatDetails : ScannerStatDetails; var powerLevelDiff : Float; var executorLevel : Float; var targetLevel : Float; var extraCost : Float; statsSystem = GameInstance.GetStatsSystem( obj.GetGame() ); currentResist = statsSystem.GetStatValue( obj.GetEntityID(), statType ); if( statType == gamedataStatType.HackingResistance && player ) { scanStatDetails.baseValue = currentResist; executorLevel = statsSystem.GetStatValue( player.GetEntityID(), gamedataStatType.PowerLevel ); targetLevel = statsSystem.GetStatValue( obj.GetEntityID(), gamedataStatType.PowerLevel ); powerLevelDiff = ( ( Float )( RoundMath( executorLevel ) - RoundF( targetLevel ) ) ); extraCost = GameInstance.GetStatsDataSystem( player.GetGame() ).GetValueFromCurve( 'puppet_dynamic_scaling', powerLevelDiff, 'pl_diff_to_memory_cost_modifier' ); currentResist += extraCost; } scanStatDetails.statType = statType; scanStatDetails.value = currentResist; return scanStatDetails; } public static function GetCharacterWeakspotCount( puppet : gamePuppet ) : Int32 { var weakspots : array< weak< Weakspot_Record > >; TweakDBInterface.GetCharacterRecord( puppet.GetRecordID() ).Weakspots( weakspots ); return weakspots.Size(); } public static function GetStatValues( obj : GameObject, const stats : ref< array< gamedataStatType > > ) : array< gameStatTotalValue > { var statsSystem : StatsSystem; var statInfos : array< gameStatTotalValue >; var statInfo : gameStatTotalValue; var i : Int32; statsSystem = GameInstance.GetStatsSystem( obj.GetGame() ); for( i = 0; i < stats.Size(); i += 1 ) { statInfo.value = statsSystem.GetStatValue( obj.GetEntityID(), stats[ i ] ); statInfo.statType = stats[ i ]; statInfos.PushBack( statInfo ); } return statInfos; } public static function GetMinStats( obj : GameObject, const stats : ref< array< gamedataStatType > > ) : array< gameStatTotalValue > { var i : Int32; var statInfos : array< gameStatTotalValue >; var minStats : array< gameStatTotalValue >; var minValue : Float; statInfos = GetStatValues( obj, stats ); minValue = MathHelper.PositiveInfinity(); for( i = 0; i < statInfos.Size(); i += 1 ) { if( statInfos[ i ].value < minValue ) { minValue = statInfos[ i ].value; minStats.Clear(); minStats.PushBack( statInfos[ i ] ); } else if( statInfos[ i ].value == minValue ) { minStats.PushBack( statInfos[ i ] ); } } return minStats; } public static function GetMaxStats( obj : GameObject, const stats : ref< array< gamedataStatType > > ) : array< gameStatTotalValue > { var i : Int32; var statInfos : array< gameStatTotalValue >; var maxStats : array< gameStatTotalValue >; var maxValue : Float; statInfos = GetStatValues( obj, stats ); maxValue = MathHelper.NegativeInfinity(); for( i = 0; i < statInfos.Size(); i += 1 ) { if( statInfos[ i ].value > maxValue ) { maxValue = statInfos[ i ].value; maxStats.Clear(); maxStats.PushBack( statInfos[ i ] ); } else if( statInfos[ i ].value == maxValue ) { maxStats.PushBack( statInfos[ i ] ); } } return maxStats; } public static function GetLowestResistances( obj : GameObject ) : array< gameStatTotalValue > { return GetMinStats( obj, ResistancesList() ); } public static function GetHighestResistances( obj : GameObject ) : array< gameStatTotalValue > { return GetMaxStats( obj, ResistancesList() ); } public static function CanPlayerCraftFromInventory( obj : weak< GameObject > ) : Bool { var val : Float; val = GameInstance.GetStatsSystem( obj.GetGame() ).GetStatValue( obj.GetEntityID(), gamedataStatType.CanCraftFromInventory ); return val > 0.0; } public static function CanPlayerUpgradeFromInventory( obj : weak< GameObject > ) : Bool { var val : Float; val = GameInstance.GetStatsSystem( obj.GetGame() ).GetStatValue( obj.GetEntityID(), gamedataStatType.CanUpgradeFromInventory ); return val > 0.0; } public static function AwardExperienceFromDamage( hitEvent : gameHitEvent, damagePercentage : Float ) { var attackData : AttackData; var queueExpRequests : array< QueueCombatExperience >; var queueExpRequest : QueueCombatExperience; var inst : GameInstance; var expAwarded : Bool; var playerDevSystem : PlayerDevelopmentSystem; var i : Int32; var targetPuppet : weak< ScriptedPuppet >; var targetPowerLevel : Float; var curveSetName : CName; var weaponRecord : weak< Item_Record >; var playerXPmultiplier : Float; var temp : Float; var additionalProf : gamedataProficiencyType; var player : weak< PlayerPuppet >; var attackRecord : weak< Attack_Record >; attackData = hitEvent.attackData; curveSetName = 'activity_to_proficiency_xp'; additionalProf = gamedataProficiencyType.Invalid; inst = hitEvent.target.GetGame(); playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( inst ).Get( 'PlayerDevelopmentSystem' ) ) ); expAwarded = true; targetPuppet = ( ( ScriptedPuppet )( hitEvent.target ) ); if( ( ( ( !( targetPuppet ) || !( targetPuppet.IsActive() ) ) || !( targetPuppet.AwardsExperience() ) ) || !( attackData.GetInstigator().IsPlayer() ) ) || hitEvent.target.IsPlayer() ) { return; } targetPowerLevel = GameInstance.GetStatsSystem( inst ).GetStatValue( targetPuppet.GetEntityID(), gamedataStatType.PowerLevel ); playerXPmultiplier = GameInstance.GetStatsSystem( inst ).GetStatValue( GetPlayer( inst ).GetEntityID(), gamedataStatType.XPbonusMultiplier ); queueExpRequest = new QueueCombatExperience; weaponRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( attackData.GetWeapon().GetItemID() ) ); switch( weaponRecord.ItemType().Type() ) { case gamedataItemType.Wea_TwoHandedClub: case gamedataItemType.Wea_Hammer: case gamedataItemType.Wea_OneHandedClub: case gamedataItemType.Wea_Melee: case gamedataItemType.Wea_Fists: case gamedataItemType.Cyb_StrongArms: queueExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); break; case gamedataItemType.Wea_Shotgun: case gamedataItemType.Wea_ShotgunDual: case gamedataItemType.Wea_HeavyMachineGun: case gamedataItemType.Wea_LightMachineGun: temp = ( ( weaponRecord.TagsContains( 'PowerWeapon' ) ) ? ( 1.0 ) : ( 0.5 ) ); queueExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ) * temp; break; case gamedataItemType.Wea_Rifle: case gamedataItemType.Wea_AssaultRifle: case gamedataItemType.Wea_SubmachineGun: temp = ( ( weaponRecord.TagsContains( 'PowerWeapon' ) ) ? ( 1.0 ) : ( 0.5 ) ); queueExpRequest.m_experienceType = gamedataProficiencyType.ReflexesSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ) * temp; break; case gamedataItemType.Wea_Katana: case gamedataItemType.Wea_Sword: case gamedataItemType.Wea_LongBlade: case gamedataItemType.Wea_ShortBlade: case gamedataItemType.Wea_Chainsword: case gamedataItemType.Wea_Machete: case gamedataItemType.Cyb_MantisBlades: queueExpRequest.m_experienceType = gamedataProficiencyType.ReflexesSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); break; case gamedataItemType.Cyb_NanoWires: queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); break; case gamedataItemType.Wea_Handgun: case gamedataItemType.Wea_Revolver: case gamedataItemType.Wea_SniperRifle: case gamedataItemType.Wea_PrecisionRifle: temp = ( ( weaponRecord.TagsContains( 'PowerWeapon' ) ) ? ( 1.0 ) : ( 0.5 ) ); queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ) * temp; break; case gamedataItemType.Wea_Knife: case gamedataItemType.Wea_Axe: queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); break; default: expAwarded = false; break; } if( ( attackData.HasFlag( hitFlag.WeakspotHit ) || attackData.HasFlag( hitFlag.Headshot ) ) || attackData.HasFlag( hitFlag.FinisherTriggered ) ) { queueExpRequest.m_amount *= 1.10000002; } if( attackData.HasFlag( hitFlag.PerfectlyCharged ) ) { queueExpRequest.m_amount *= 1.10000002; } if( attackData.HasFlag( hitFlag.BodyPerksMeleeAttack ) ) { queueExpRequest.m_amount *= 1.10000002; } if( expAwarded ) { if( StatusEffectSystem.ObjectHasStatusEffectWithTag( attackData.GetInstigator(), 'TrainingGuns' ) && attackData.GetWeapon().IsRanged() ) { queueExpRequest.m_amount *= 2.0; } if( StatusEffectSystem.ObjectHasStatusEffectWithTag( attackData.GetInstigator(), 'TrainingMelee' ) && attackData.GetWeapon().IsMelee() ) { queueExpRequest.m_amount *= 2.0; } queueExpRequests.PushBack( queueExpRequest ); if( weaponRecord.TagsContains( 'SmartWeapon' ) ) { additionalProf = gamedataProficiencyType.IntelligenceSkill; } else if( weaponRecord.TagsContains( 'TechWeapon' ) ) { additionalProf = gamedataProficiencyType.TechnicalAbilitySkill; } if( additionalProf != gamedataProficiencyType.Invalid ) { temp = queueExpRequest.m_amount; queueExpRequest = new QueueCombatExperience; queueExpRequest.m_experienceType = additionalProf; queueExpRequest.m_amount = temp; queueExpRequests.PushBack( queueExpRequest ); } } if( attackData.GetAttackType() == gamedataAttackType.Hack ) { queueExpRequest = new QueueCombatExperience; queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); queueExpRequests.PushBack( queueExpRequest ); } attackRecord = ( ( Attack_GameEffect_Record )( attackData.GetAttackDefinition().GetRecord() ) ); if( ( ( ( BaseGrenade )( attackData.GetSource() ) ) || ( ( ProjectileLauncherRound )( attackData.GetSource() ) ) ) || attackRecord.HitFlagsContains( "Grenade" ) ) { queueExpRequest = new QueueCombatExperience; queueExpRequest.m_experienceType = gamedataProficiencyType.TechnicalAbilitySkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ); queueExpRequests.PushBack( queueExpRequest ); } if( hitEvent.attackData.HasFlag( hitFlag.StealthHit ) ) { queueExpRequest = new QueueCombatExperience; queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill; queueExpRequest.m_amount = GameInstance.GetStatsDataSystem( inst ).GetValueFromCurve( curveSetName, targetPowerLevel, 'damage_to_skill_xp' ) * 0.69999999; queueExpRequests.PushBack( queueExpRequest ); } player = GetPlayer( inst ); for( i = 0; i < queueExpRequests.Size(); i += 1 ) { queueExpRequest = queueExpRequests[ i ]; queueExpRequest.owner = player; queueExpRequest.m_amount *= RPGManager.GetRarityMultiplier( ( ( NPCPuppet )( hitEvent.target ) ), 'power_level_to_dmg_xp_mult' ); queueExpRequest.m_amount *= damagePercentage; queueExpRequest.m_amount *= playerXPmultiplier; queueExpRequest.m_entity = targetPuppet.GetEntityID(); playerDevSystem.QueueRequest( queueExpRequest ); } if( ( ( ( ( ( attackData.HasFlag( hitFlag.WasKillingBlow ) || attackData.HasFlag( hitFlag.FinisherTriggered ) ) && StatusEffectSystem.ObjectHasStatusEffect( attackData.GetInstigator(), T"BaseStatusEffect.Intelligence_Central_Milestone_3_Overclock_Buff" ) ) || StatusEffectSystem.ObjectHasStatusEffect( attackData.GetInstigator(), T"BaseStatusEffect.Tech_Master_Perk_3_Buff" ) ) || StatusEffectSystem.ObjectHasStatusEffectOfType( attackData.GetInstigator(), gamedataStatusEffectType.Berserk ) ) || StatusEffectSystem.ObjectHasStatusEffectOfType( attackData.GetInstigator(), gamedataStatusEffectType.Sandevistan ) ) || StatusEffectSystem.ObjectHasStatusEffectWithTag( attackData.GetInstigator(), 'CamoActiveOnPlayer' ) ) { queueExpRequest = new QueueCombatExperience; queueExpRequest.owner = player; queueExpRequest.m_experienceType = gamedataProficiencyType.TechnicalAbilitySkill; queueExpRequest.m_amount = 20.0 * playerXPmultiplier; queueExpRequest.m_entity = targetPuppet.GetEntityID(); playerDevSystem.QueueRequest( queueExpRequest ); } } public static function AwardExperienceFromDeflect( hitEvent : gameHitEvent ) { var queueExpRequest : QueueCombatExperience; var blockingItem : weak< WeaponObject >; var playerXPmultiplier : Float; var gameInstance : GameInstance; var playerDevSystem : PlayerDevelopmentSystem; var statPoolsSystem : StatPoolsSystem; var player : weak< PlayerPuppet >; var damage : Float; var health, healthPercent : Float; var parryEffect : weak< StatusEffect >; player = ( ( PlayerPuppet )( hitEvent.target ) ); if( !( player ) ) { return; } gameInstance = player.GetGame(); blockingItem = ( ( WeaponObject )( GameInstance.GetTransactionSystem( gameInstance ).GetItemInSlot( player, T"AttachmentSlots.WeaponRight" ) ) ); if( !( blockingItem ) ) { return; } statPoolsSystem = GameInstance.GetStatPoolsSystem( gameInstance ); damage = hitEvent.attackComputed.GetTotalAttackValue( gamedataStatPoolType.Health ); healthPercent = statPoolsSystem.GetStatPoolValue( player.GetEntityID(), gamedataStatPoolType.Health ); health = statPoolsSystem.ToPoints( player.GetEntityID(), gamedataStatPoolType.Health, healthPercent ); damage = ( damage * healthPercent ) / health; parryEffect = StatusEffectHelper.GetStatusEffectByID( player, T"BaseStatusEffect.ParryExpHarvested" ); if( ( damage <= 0.0 ) || ( parryEffect && ( parryEffect.GetMaxStacks() <= parryEffect.GetStackCount() ) ) ) { return; } playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'PlayerDevelopmentSystem' ) ) ); playerXPmultiplier = GameInstance.GetStatsSystem( gameInstance ).GetStatValue( player.GetEntityID(), gamedataStatType.XPbonusMultiplier ); queueExpRequest = new QueueCombatExperience; queueExpRequest.owner = player; queueExpRequest.m_entity = hitEvent.attackData.GetInstigator().GetEntityID(); queueExpRequest.m_amount = ( damage * playerXPmultiplier ) * 0.75; if( blockingItem.IsBlunt() ) { queueExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill; playerDevSystem.QueueRequest( queueExpRequest ); } else if( blockingItem.IsBlade() ) { queueExpRequest.m_experienceType = gamedataProficiencyType.ReflexesSkill; playerDevSystem.QueueRequest( queueExpRequest ); } StatusEffectHelper.ApplyStatusEffect( hitEvent.attackData.GetInstigator(), T"BaseStatusEffect.ParryExpHarvested", player.GetEntityID() ); } public static function AwardExperienceFromLocomotion( player : weak< PlayerPuppet >, amount : Float ) { var queueExpRequest : AddExperience; var playerDevSystem : PlayerDevelopmentSystem; var statsSystem : StatsSystem; var cachedExp : Int32; var statMod : gameConstantStatModifierData; var statusEffect : StatusEffect; var gameInstance : GameInstance; var playerXPmultiplier : Float; var stat : gamedataStatType; stat = gamedataStatType.LocomotionExperienceReward; if( !( player ) || ( amount <= 0.0 ) ) { return; } statusEffect = StatusEffectHelper.GetStatusEffectByID( player, T"BaseStatusEffect.LocomotionExpHarvested" ); if( statusEffect && ( statusEffect.GetMaxStacks() <= statusEffect.GetStackCount() ) ) { return; } gameInstance = player.GetGame(); playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'PlayerDevelopmentSystem' ) ) ); statsSystem = GameInstance.GetStatsSystem( gameInstance ); playerXPmultiplier = GameInstance.GetStatsSystem( gameInstance ).GetStatValue( player.GetEntityID(), gamedataStatType.XPbonusMultiplier ); statMod = ( ( gameConstantStatModifierData )( RPGManager.CreateStatModifier( stat, gameStatModifierType.Additive, amount * playerXPmultiplier ) ) ); statsSystem.AddModifier( player.GetEntityID(), statMod ); cachedExp = ( ( Int32 )( statsSystem.GetStatValue( player.GetEntityID(), stat ) ) ); if( cachedExp >= 100 ) { queueExpRequest = new AddExperience; queueExpRequest.Set( player, cachedExp, gamedataProficiencyType.ReflexesSkill, false ); playerDevSystem.QueueRequest( queueExpRequest ); statMod = ( ( gameConstantStatModifierData )( RPGManager.CreateStatModifier( stat, gameStatModifierType.Additive, ( ( Float )( cachedExp ) ) * -1.0 ) ) ); statsSystem.AddModifier( player.GetEntityID(), statMod ); } StatusEffectHelper.ApplyStatusEffect( player, T"BaseStatusEffect.LocomotionExpHarvested", player.GetEntityID() ); } public static function AwardExperienceFromResourceSpent( player : weak< PlayerPuppet >, value : Float, type : gamedataStatPoolType, optional hitEvent : gameHitEvent ) { var queueCombatExpRequest : QueueCombatExperience; var playerXPmultiplier : Float; var gameInstance : GameInstance; var playerDevSystem : PlayerDevelopmentSystem; if( !( player ) ) { return; } gameInstance = player.GetGame(); playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'PlayerDevelopmentSystem' ) ) ); playerXPmultiplier = GameInstance.GetStatsSystem( gameInstance ).GetStatValue( player.GetEntityID(), gamedataStatType.XPbonusMultiplier ); if( ( ( type == gamedataStatPoolType.Overshield && hitEvent ) && !( hitEvent.attackData.GetInstigator().IsPlayer() ) ) && hitEvent.target.IsPlayer() ) { queueCombatExpRequest = new QueueCombatExperience; queueCombatExpRequest.owner = player; queueCombatExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill; queueCombatExpRequest.m_amount = ( value * playerXPmultiplier ) * 0.25; queueCombatExpRequest.m_entity = hitEvent.attackData.GetInstigator().GetEntityID(); playerDevSystem.QueueRequest( queueCombatExpRequest ); } } public static function AwardExperienceFromQuickhack( player : weak< PlayerPuppet >, cost : Float, target : EntityID, category : gamedataHackCategory ) { var playerXPmultiplier : Float; var playerDevSystem : PlayerDevelopmentSystem; var queueExpRequest : AddExperience; var gameInstance : GameInstance; var multiplier : Float; var targetPowerLevel : Float; var statusEffect : weak< StatusEffect >; var targetObj : weak< GameObject >; multiplier = 1.0; if( ( !( player ) || !( EntityID.IsDefined( target ) ) ) || category == gamedataHackCategory.NotAHack ) { return; } targetObj = ( ( GameObject )( GameInstance.FindEntityByID( gameInstance, target ) ) ); statusEffect = StatusEffectHelper.GetStatusEffectByID( targetObj, T"BaseStatusEffect.QuickhackExpHarvested" ); if( statusEffect && ( statusEffect.GetMaxStacks() <= statusEffect.GetStackCount() ) ) { return; } gameInstance = player.GetGame(); playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'PlayerDevelopmentSystem' ) ) ); playerXPmultiplier = GameInstance.GetStatsSystem( gameInstance ).GetStatValue( player.GetEntityID(), gamedataStatType.XPbonusMultiplier ); targetPowerLevel = GameInstance.GetStatsSystem( gameInstance ).GetStatValue( target, gamedataStatType.PowerLevel ); if( GameInstance.GetStatsSystem( gameInstance ).GetStatValue( target, gamedataStatType.WasQuickHacked ) < 1.0 ) { multiplier = 20.0; } if( category == gamedataHackCategory.DeviceHack ) { multiplier *= 0.30000001; } queueExpRequest = new AddExperience; queueExpRequest.owner = player; queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill; queueExpRequest.m_amount = ( ( Int32 )( ( ( ( ( cost * 0.69999999 ) + ( targetPowerLevel * 0.2 ) ) * playerXPmultiplier ) * multiplier ) * 0.5 ) ); playerDevSystem.QueueRequest( queueExpRequest ); StatusEffectHelper.ApplyStatusEffect( targetObj, T"BaseStatusEffect.QuickhackExpHarvested", player.GetEntityID() ); } public static function AwardExperienceInstantly( player : weak< PlayerPuppet >, amount : Int32, type : gamedataProficiencyType ) { var queueExpRequest : AddExperience; var playerDevSystem : PlayerDevelopmentSystem; queueExpRequest = new AddExperience; if( !( player ) || ( amount <= 0 ) ) { return; } playerDevSystem = ( ( PlayerDevelopmentSystem )( GameInstance.GetScriptableSystemsContainer( player.GetGame() ).Get( 'PlayerDevelopmentSystem' ) ) ); queueExpRequest = new AddExperience; queueExpRequest.Set( player, amount, type, false ); playerDevSystem.QueueRequest( queueExpRequest ); } public static function CalculateMinorActivityReward( gi : GameInstance, experienceValue : Float ) : Float { var maPrologueMultiplier : Float; var maDynamicMultiplier : Float; var maCount : Int32; var factVal : Int32; var experienceReward : Float; var maxExperience : Int32; var maAmount : Int32; var baseReward : Int32; maDynamicMultiplier = 1.0; maPrologueMultiplier = TDB.GetFloat( T"Constants.RPGManager.maPrologueMultiplier" ); maxExperience = TDB.GetInt( T"Constants.RPGManager.maDesiredExperience" ); maAmount = TDB.GetInt( T"Constants.RPGManager.maAmount" ); baseReward = TDB.GetInt( T"Constants.RPGManager.maBaseReward" ); if( GetFact( gi, 'q005_done' ) <= 0 ) { experienceReward = experienceValue * maPrologueMultiplier; factVal = GetFact( gi, 'prologue_ma_done' ); SetFactValue( gi, 'prologue_ma_done', factVal + 1 ); SetFactValue( gi, 'maExperienceSum', GetFact( gi, 'maExperienceSum' ) + ( ( Int32 )( experienceReward ) ) ); } else { maCount = GetFact( gi, 'prologue_ma_done' ); if( ( maAmount - maCount ) > 0 ) { maDynamicMultiplier = ( ( ( ( Float )( maxExperience ) ) - ( ( Float )( GetFact( gi, 'maExperienceSum' ) ) ) ) / ( ( ( Float )( maAmount ) ) - ( ( Float )( maCount ) ) ) ) / ( ( Float )( baseReward ) ); } experienceReward = experienceValue * maDynamicMultiplier; } return experienceReward; } public static function CalculateStreetStoryReward( gi : GameInstance, experienceValue : Float ) : Float { var stsPrologueMultiplier : Float; var stsDynamicMultiplier : Float; var stsCount : Int32; var factVal : Int32; var experienceReward : Float; var maxExperience : Int32; var stsAmount : Int32; var baseReward : Int32; stsDynamicMultiplier = 1.0; stsPrologueMultiplier = TDB.GetFloat( T"Constants.RPGManager.stsPrologueMultiplier" ); maxExperience = TDB.GetInt( T"Constants.RPGManager.stsDesiredExperience" ); stsAmount = TDB.GetInt( T"Constants.RPGManager.stsAmount" ); baseReward = TDB.GetInt( T"Constants.RPGManager.stsBaseReward" ); if( GetFact( gi, 'q005_done' ) <= 0 ) { experienceReward = experienceValue * stsPrologueMultiplier; factVal = GetFact( gi, 'prologue_sts_done' ); SetFactValue( gi, 'prologue_sts_done', factVal + 1 ); SetFactValue( gi, 'stsExperienceSum', GetFact( gi, 'stsExperienceSum' ) + ( ( Int32 )( experienceReward ) ) ); } else { stsCount = GetFact( gi, 'prologue_sts_done' ); if( ( stsAmount - stsCount ) > 0 ) { stsDynamicMultiplier = ( ( ( ( Float )( maxExperience ) ) - ( ( Float )( GetFact( gi, 'stsExperienceSum' ) ) ) ) / ( ( ( Float )( stsAmount ) ) - ( ( Float )( stsCount ) ) ) ) / ( ( Float )( baseReward ) ); } experienceReward = experienceValue * stsDynamicMultiplier; } return experienceReward; } public static function CalculateEP1Reward( gi : GameInstance, experienceValue : Float, playerLevel : Float ) : Float { var experienceReward : Float; var statsDataSystem : StatsDataSystem; var levelMult : Float; statsDataSystem = GameInstance.GetStatsDataSystem( gi ); levelMult = statsDataSystem.GetValueFromCurve( 'player_level_to_xp_multiplier', playerLevel, 'player_level_to_xp_mult' ); experienceReward = experienceValue * levelMult; return experienceReward; } public static function GiveReward( gi : GameInstance, rewardID : TweakDBID, optional target : StatsObjectID, optional moneyMultiplier : Float ) { GiveReward( gi, rewardID, 1, target, moneyMultiplier ); } public static function GiveReward( gi : GameInstance, rewardID : TweakDBID, amount : Int32, optional target : StatsObjectID, optional moneyMultiplier : Float ) { var i : Int32; var quantity : Int32; var rewardName : String; var rewardRecord : RewardBase_Record; var itemArr : array< weak< InventoryItem_Record > >; var expArr : array< weak< XPPoints_Record > >; var currencyArr : array< weak< CurrencyReward_Record > >; var quantityMods : array< weak< StatModifier_Record > >; var recipesArr : array< weak< Item_Record > >; var achievementsArr : array< weak< Achievement_Record > >; var photoModeItmsArr : array< weak< PhotoModeItem_Record > >; var expEvt : ExperiencePointsEvent; var transSys : TransactionSystem; var visualizer : DebugVisualizerSystem; var statsDataSystem : StatsDataSystem; var expType : gamedataProficiencyType; var player : PlayerPuppet; var addRecipeRequest : AddRecipeRequest; var craftingSystem : CraftingSystem; var NCPDJobDone : NCPDJobDoneEvent; var itemID : ItemID; var powerDiff : gameEPowerDifferential; var contentAssignment : TweakDBID; var experienceValue : Float; var playerLevel : Float; var playerXPmultiplier : Float; var streetCredXPmultiplier : Float; var contentLevel : Int32; var levelDiff : Int32; var currencyItemID : ItemID; var moneyQuantity : Int32; var calculateXPOldSaves : Bool; var courierMoneyMultiplier : Float; var moneyCalc : Float; var factVal : Int32; var courierMissionsDone : Float; craftingSystem = ( ( CraftingSystem )( GameInstance.GetScriptableSystemsContainer( gi ).Get( 'CraftingSystem' ) ) ); transSys = GameInstance.GetTransactionSystem( gi ); visualizer = GameInstance.GetDebugVisualizerSystem( gi ); statsDataSystem = GameInstance.GetStatsDataSystem( gi ); rewardRecord = TweakDBInterface.GetRewardBaseRecord( rewardID ); if( !( rewardRecord ) ) { return; } player = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( gi ).GetLocalPlayerControlledGameObject() ) ); NCPDJobDone = new NCPDJobDoneEvent; rewardName = rewardRecord.Name(); if( rewardName != "" ) { visualizer.DrawText( Vector4( 5.0, 350.0, 0.0, 0.0 ), rewardName, gameDebugViewETextAlignment.Left, Color( 255, 128, 0, 255 ), 1.5 ); } else { rewardName = "GiveReward(): No reward name found"; visualizer.DrawText( Vector4( 5.0, 350.0, 0.0, 0.0 ), rewardName, gameDebugViewETextAlignment.Left, Color( 255, 128, 0, 255 ), 1.5 ); } rewardRecord.Items( itemArr ); for( i = 0; i < itemArr.Size(); i += 1 ) { quantity = itemArr[ i ].Quantity() * amount; itemID = ItemID.FromTDBID( itemArr[ i ].Item().GetID() ); transSys.GiveItem( player, ItemID.FromTDBID( itemArr[ i ].Item().GetID() ), quantity ); GameInstance.GetTelemetrySystem( player.GetGame() ).LogItemReward( player, itemID ); } rewardRecord.Recipes( recipesArr ); for( i = 0; i < recipesArr.Size(); i += 1 ) { addRecipeRequest = new AddRecipeRequest; addRecipeRequest.owner = player; addRecipeRequest.amount = 1; addRecipeRequest.recipe = recipesArr[ i ].GetID(); craftingSystem.QueueRequest( addRecipeRequest ); GameInstance.GetTelemetrySystem( player.GetGame() ).LogItemReward( player, ItemID.FromTDBID( recipesArr[ i ].GetID() ) ); } rewardRecord.Experience( expArr ); playerXPmultiplier = GameInstance.GetStatsSystem( player.GetGame() ).GetStatValue( player.GetEntityID(), gamedataStatType.XPbonusMultiplier ); streetCredXPmultiplier = GameInstance.GetStatsSystem( player.GetGame() ).GetStatValue( player.GetEntityID(), gamedataStatType.StreetCredXPBonusMultiplier ) / 100.0; for( i = 0; i < expArr.Size(); i += 1 ) { expEvt = new ExperiencePointsEvent; quantityMods.Clear(); expArr[ i ].QuantityModifiers( quantityMods ); experienceValue = RPGManager.CalculateStatModifiers( quantityMods, player.GetGame(), player, target ); expType = expArr[ i ].Type().Type(); expEvt.type = expType; expEvt.isDebug = false; if( expType != gamedataProficiencyType.Level && expType != gamedataProficiencyType.StreetCred ) { experienceValue *= playerXPmultiplier; } else if( expType == gamedataProficiencyType.StreetCred ) { experienceValue *= ( 1.0 + streetCredXPmultiplier ); } contentAssignment = TweakDBInterface.GetForeignKey( rewardID + T".contentAssignment", T"" ); if( TDBID.IsValid( contentAssignment ) ) { playerLevel = GameInstance.GetStatsSystem( player.GetGame() ).GetStatValue( player.GetEntityID(), gamedataStatType.PowerLevel ); contentLevel = GameInstance.GetLevelAssignmentSystem( player.GetGame() ).GetLevelAssignment( contentAssignment ); levelDiff = RoundMath( playerLevel - ( ( Float )( contentLevel ) ) ); powerDiff = CalculatePowerDifferential( levelDiff ); switch( powerDiff ) { case gameEPowerDifferential.TRASH: experienceValue *= 0.80000001; break; case gameEPowerDifferential.EASY: experienceValue *= 0.89999998; break; case gameEPowerDifferential.HARD: experienceValue *= 1.10000002; break; case gameEPowerDifferential.IMPOSSIBLE: experienceValue *= 1.20000005; break; default: break; } } expEvt.amount = ( ( Int32 )( experienceValue ) ) * amount; rewardName = StrLower( rewardName ); if( expType == gamedataProficiencyType.Level ) { calculateXPOldSaves = GetFact( gi, 'CalculateXPOldSaves' ); if( StrBeginsWith( rewardName, "ma_" ) && !( calculateXPOldSaves ) ) { expEvt.amount = ( ( Int32 )( CalculateMinorActivityReward( gi, experienceValue ) ) ); } else if( ( StrBeginsWith( rewardName, "sts_" ) && !( StrBeginsWith( rewardName, "sts_ep1" ) ) ) && !( calculateXPOldSaves ) ) { expEvt.amount = ( ( Int32 )( CalculateStreetStoryReward( gi, experienceValue ) ) ); } else if( ( ( StrBeginsWith( rewardName, "q3" ) || StrBeginsWith( rewardName, "mq3" ) ) || StrBeginsWith( rewardName, "sts_ep1" ) ) || StrBeginsWith( rewardName, "sa_ep1" ) ) { playerLevel = GameInstance.GetStatsSystem( player.GetGame() ).GetStatValue( player.GetEntityID(), gamedataStatType.Level ); expEvt.amount = ( ( Int32 )( CalculateEP1Reward( gi, experienceValue, playerLevel ) ) ); } } GameInstance.GetTelemetrySystem( gi ).LogXPReward( expArr[ i ].GetID(), expEvt.amount, expEvt.type ); player.QueueEvent( expEvt ); if( expType == gamedataProficiencyType.Level ) { NCPDJobDone.levelXPAwarded = expEvt.amount; } else if( expType == gamedataProficiencyType.StreetCred ) { NCPDJobDone.streetCredXPAwarded = expEvt.amount; } } moneyQuantity = 0; rewardRecord.CurrencyPackage( currencyArr ); for( i = 0; i < currencyArr.Size(); i += 1 ) { quantityMods.Clear(); currencyArr[ i ].QuantityModifiers( quantityMods ); quantity = ( ( Int32 )( RPGManager.CalculateStatModifiers( quantityMods, player.GetGame(), player, target ) ) ); if( quantity > 0 ) { quantity = ( ( moneyMultiplier > 0.0 ) ? ( ( ( Int32 )( ( ( Float )( quantity ) ) * moneyMultiplier ) ) ) : ( quantity ) ); quantity *= amount; currencyItemID = ItemID.FromTDBID( currencyArr[ i ].Currency().GetID() ); if( StrBeginsWith( rewardName, "sa_ep1_courier_tier" ) ) { factVal = GetFact( gi, 'courier_missions_done' ); courierMissionsDone = ( ( Float )( factVal ) ); courierMoneyMultiplier = statsDataSystem.GetValueFromCurve( 'activities_done_to_money_multiplier', courierMissionsDone, 'courier_done_to_money_mult' ); moneyCalc = ( ( courierMoneyMultiplier > 0.0 ) ? ( ( ( Float )( quantity ) ) * courierMoneyMultiplier ) : ( ( ( Float )quantity ) ) ); quantity = ( ( Int32 )( moneyCalc ) ); SetFactValue( gi, 'courier_missions_done', factVal + 1 ); } transSys.GiveItem( player, currencyItemID, quantity ); if( currencyItemID == MarketSystem.Money() ) { moneyQuantity += quantity; } } } rewardRecord.Achievement( achievementsArr ); for( i = 0; i < achievementsArr.Size(); i += 1 ) { SendAddAchievementRequest( gi, achievementsArr[ i ].Type(), achievementsArr[ i ] ); } rewardRecord.PhotoModeItem( photoModeItmsArr ); for( i = 0; i < photoModeItmsArr.Size(); i += 1 ) { SendPhotoModeItemUnlockRequest( gi, photoModeItmsArr[ i ] ); } if( StrBeginsWith( rewardName, "ma_" ) ) { GameInstance.GetUISystem( gi ).QueueEvent( NCPDJobDone ); } GameInstance.GetTelemetrySystem( gi ).LogRewardGiven( StringToName( rewardName ), rewardID, moneyQuantity ); } public static function AwardXP( gi : GameInstance, amount : Float, type : gamedataProficiencyType ) { var xpEvent : ExperiencePointsEvent; var statsSystem : StatsSystem; var playerXPmultiplier : Float; var awardXP : Float; statsSystem = GameInstance.GetStatsSystem( gi ); playerXPmultiplier = statsSystem.GetStatValue( GetPlayer( gi ).GetEntityID(), gamedataStatType.XPbonusMultiplier ); awardXP = amount * playerXPmultiplier; xpEvent = new ExperiencePointsEvent; xpEvent.amount = ( ( Int32 )( awardXP ) ); xpEvent.type = type; GetPlayer( gi ).QueueEvent( xpEvent ); } private static function SendAddAchievementRequest( gi : GameInstance, achievement : gamedataAchievement, achievementRecord : weak< Achievement_Record > ) { var request : AddAchievementRequest; request = new AddAchievementRequest; request.achievement = achievement; GameInstance.GetScriptableSystemsContainer( gi ).Get( 'DataTrackingSystem' ).QueueRequest( request ); } private static function SendPhotoModeItemUnlockRequest( gi : GameInstance, photoModeItm : weak< PhotoModeItem_Record > ) { var tweakID : TweakDBID; tweakID = photoModeItm.GetID(); GameInstance.GetPhotoModeSystem( gi ).UnlockPhotoModeItem( tweakID ); } public static function GiveScavengeReward( gi : GameInstance, rewardID : TweakDBID, scavengeTargetEntityID : EntityID ) { GiveReward( gi, rewardID ); } public static function PrepareGameEffectAttack( gi : GameInstance, instigator : GameObject, source : GameObject, attackName : TweakDBID, optional position : Vector4, optional hitFlags : array< SHitFlag >, optional target : GameObject, optional tickRateOverride : Float ) : Attack_GameEffect { var attack : Attack_GameEffect; var attackRecord : Attack_GameEffect_Record; var attackContext : AttackInitContext; var attackEffect : EffectInstance; var statMods : array< gameStatModifierData >; var sharedData : EffectData; var effectDef : EffectSharedDataDef; attackRecord = ( ( Attack_GameEffect_Record )( TweakDBInterface.GetAttackRecord( attackName ) ) ); if( attackRecord ) { attackContext.record = attackRecord; attackContext.instigator = instigator; attackContext.source = source; attack = ( ( Attack_GameEffect )( IAttack.Create( attackContext ) ) ); attackEffect = attack.PrepareAttack( instigator ); attack.GetStatModList( statMods ); if( position == Vector4.EmptyVector() ) { position = source.GetWorldPosition(); } sharedData = attackEffect.GetSharedData(); effectDef = GetAllBlackboardDefs().EffectSharedData; EffectData.SetFloat( sharedData, effectDef.radius, attackRecord.Range() ); EffectData.SetVector( sharedData, effectDef.position, position ); EffectData.SetVariant( sharedData, effectDef.attack, ( ( IAttack )( attack ) ) ); EffectData.SetVariant( sharedData, effectDef.attackStatModList, statMods ); EffectData.SetVariant( sharedData, effectDef.flags, hitFlags ); EffectData.SetEntity( sharedData, effectDef.entity, target ); if( tickRateOverride > 0.0 ) { EffectData.SetFloat( sharedData, effectDef.tickRateOverride, tickRateOverride ); } EffectData.SetName( sharedData, effectDef.slotName, 'Head' ); return attack; } return attack; } public static function ExtractItemsOfEquipArea( type : gamedataEquipmentArea, const input : ref< array< weak< gameItemData > > >, output : ref< array< weak< gameItemData > > > ) : Bool { var i : Int32; var itemsFound : Bool; for( i = 0; i < input.Size(); i += 1 ) { if( TweakDBInterface.GetItemRecord( ItemID.GetTDBID( input[ i ].GetID() ) ).EquipArea().Type() == type ) { output.PushBack( input[ i ] ); itemsFound = true; } } return itemsFound; } public static function GetAmmoCount( owner : GameObject, itemID : ItemID ) : String { var itemRecord : Item_Record; var weaponRecord : WeaponItem_Record; var category : gamedataItemCategory; var ammoQuery : ItemID; var ammoCount : Int32; var transSystem : TransactionSystem; transSystem = GameInstance.GetTransactionSystem( owner.GetGame() ); itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ); category = itemRecord.ItemCategory().Type(); if( category == gamedataItemCategory.Gadget || category == gamedataItemCategory.Consumable ) { ammoQuery = ItemID.CreateQuery( ItemID.GetTDBID( itemID ) ); ammoCount = transSystem.GetItemQuantity( owner, ammoQuery ); return ( ( String )( ammoCount ) ); } else if( category == gamedataItemCategory.Weapon ) { weaponRecord = ( ( WeaponItem_Record )( itemRecord ) ); ammoQuery = ItemID.CreateQuery( weaponRecord.Ammo().GetID() ); ammoCount = transSystem.GetItemQuantity( owner, ammoQuery ); } if( ammoCount > 0 ) { return ( ( String )( ammoCount ) ); } else { return ""; } } public static function GetAmmoCountValue( owner : GameObject, itemID : ItemID ) : Int32 { var itemRecord : Item_Record; var weaponRecord : WeaponItem_Record; var category : gamedataItemCategory; var ammoQuery : ItemID; var ammoCount : Int32; var transSystem : TransactionSystem; transSystem = GameInstance.GetTransactionSystem( owner.GetGame() ); itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ); if( itemRecord ) { category = itemRecord.ItemCategory().Type(); } if( category == gamedataItemCategory.Gadget || category == gamedataItemCategory.Consumable ) { ammoQuery = ItemID.CreateQuery( ItemID.GetTDBID( itemID ) ); ammoCount = transSystem.GetItemQuantity( owner, ammoQuery ); return ammoCount; } else if( category == gamedataItemCategory.Weapon && itemRecord ) { weaponRecord = ( ( WeaponItem_Record )( itemRecord ) ); ammoQuery = ItemID.CreateQuery( weaponRecord.Ammo().GetID() ); ammoCount = transSystem.GetItemQuantity( owner, ammoQuery ); } return ammoCount; } public static function GetWeaponAmmoTDBID( weaponID : ItemID ) : TweakDBID { return TweakDBInterface.GetWeaponItemRecord( ItemID.GetTDBID( weaponID ) ).Ammo().GetID(); } public static function GetItemRecord( itemID : ItemID ) : Item_Record { return TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ); } public static function GetAttachmentSlotID( const slot : ref< String > ) : TweakDBID { return TDBID.Create( "AttachmentSlots." + slot ); } public static function ForceEquipItemOnPlayer( puppet : GameObject, itemTDBID : TweakDBID, addToInv : Bool ) { var itemID : ItemID; var equipRequest : EquipRequest; if( ( puppet == NULL ) || !( ( ( PlayerPuppet )( puppet ) ) ) ) { return; } itemID = ItemID.FromTDBID( itemTDBID ); equipRequest = new EquipRequest; equipRequest.itemID = itemID; equipRequest.owner = puppet; equipRequest.addToInventory = addToInv; GameInstance.GetScriptableSystemsContainer( puppet.GetGame() ).Get( 'EquipmentSystem' ).QueueRequest( equipRequest ); } public static function GetItemActions( itemID : ItemID ) : array< weak< ObjectAction_Record > > { var actions : array< weak< ObjectAction_Record > >; TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ).ObjectActions( actions ); return actions; } public static function IsTechPierceEnabled( gi : GameInstance, owner : GameObject, itemID : ItemID ) : Bool { return GameInstance.GetTransactionSystem( gi ).GetItemData( owner, itemID ).GetStatValueByType( gamedataStatType.TechPierceEnabled ) > 0.0; } public static function IsRicochetChanceEnabled( gi : GameInstance, owner : GameObject, itemID : ItemID ) : Bool { var itemData : gameItemData; itemData = GameInstance.GetTransactionSystem( gi ).GetItemData( owner, itemID ); if( itemData ) { return itemData.GetStatValueByType( gamedataStatType.RicochetChance ) > 0.0; } return false; } public static function HasSmartLinkRequirement( itemData : gameItemData ) : Bool { if( itemData ) { return itemData.GetStatValueByType( gamedataStatType.ItemRequiresSmartLink ) > 0.0; } return false; } public static function CanPartBeUnequipped( data : InventoryItemData, slotId : TweakDBID ) : Bool { var itemID : ItemID; var type : gamedataItemType; itemID = data.ID; type = RPGManager.GetItemType( itemID ); if( IsWeaponMod( type ) || IsClothingMod( type ) ) { return true; } else if( type == gamedataItemType.Prt_Fragment ) { return !( IsNonModifableSlot( slotId ) ); } else if( ( ( ( ( ( ( type == gamedataItemType.Prt_ShortScope || type == gamedataItemType.Prt_LongScope ) || type == gamedataItemType.Prt_TechSniperScope ) || type == gamedataItemType.Prt_PowerSniperScope ) || type == gamedataItemType.Prt_Muzzle ) || type == gamedataItemType.Prt_HandgunMuzzle ) || type == gamedataItemType.Prt_RifleMuzzle ) || type == gamedataItemType.Prt_Program ) { return true; } else { return false; } } private static function IsNonModifableSlot( slot : TweakDBID ) : Bool { return ( ( ( slot == T"AttachmentSlots.StrongArmsKnuckles" ) || ( slot == T"AttachmentSlots.MantisBladesEdge" ) ) || ( slot == T"AttachmentSlots.NanoWiresCable" ) ) || ( slot == T"AttachmentSlots.ProjectileLauncherRound" ); } public static function CanItemBeDropped( puppet : GameObject, itemData : gameItemData ) : Bool { var blackboard : IBlackboard; var consumableBeingUsed : ItemID; blackboard = GameInstance.GetBlackboardSystem( puppet.GetGame() ).Get( GetAllBlackboardDefs().UI_QuickSlotsData ); consumableBeingUsed = ( ( ItemID )( blackboard.GetVariant( GetAllBlackboardDefs().UI_QuickSlotsData.consumableBeingUsed ) ) ); if( itemData ) { if( ItemID.IsValid( consumableBeingUsed ) && ( TweakDBInterface.GetConsumableItemRecord( ItemID.GetTDBID( itemData.GetID() ) ) == TweakDBInterface.GetConsumableItemRecord( ItemID.GetTDBID( consumableBeingUsed ) ) ) ) { return false; } return ( ( !( itemData.HasTag( 'IconicWeapon' ) ) && !( itemData.HasTag( 'Quest' ) ) ) && !( itemData.HasTag( 'UnequipBlocked' ) ) ) && ItemActionsHelper.GetDropAction( itemData.GetID() ); } return false; } public static function CanItemBeDisassembled( gameInstance : GameInstance, itemID : ItemID ) : Bool { return CraftingSystem.GetInstance( gameInstance ).CanItemBeDisassembled( GetPlayer( gameInstance ), itemID ); } public static function HasDownloadFundsAction( itemID : ItemID ) : Bool { var i : Int32; var actions : array< weak< ObjectAction_Record > >; actions = RPGManager.GetItemActions( itemID ); for( i = 0; i < actions.Size(); i += 1 ) { if( actions[ i ].ActionName() == 'DownloadFunds' ) { return true; } } return false; } public static function CanDownloadFunds( gi : GameInstance, itemID : ItemID ) : Bool { var i : Int32; var fact : CName; var actions : array< weak< ObjectAction_Record > >; actions = RPGManager.GetItemActions( itemID ); for( i = 0; i < actions.Size(); i += 1 ) { if( actions[ i ].ActionName() == 'DownloadFunds' ) { fact = TweakDBInterface.GetCName( actions[ i ].GetID() + T".factToCheck", '' ); if( IsNameValid( fact ) && ( GetFact( gi, fact ) <= 0 ) ) { return true; } } } return false; } public static function CanItemBeDisassembled( gameInstance : GameInstance, itemData : weak< gameItemData > ) : Bool { var CS : CraftingSystem; var blackboard : IBlackboard; var consumableBeingUsed : ItemID; blackboard = GameInstance.GetBlackboardSystem( gameInstance ).Get( GetAllBlackboardDefs().UI_QuickSlotsData ); consumableBeingUsed = ( ( ItemID )( blackboard.GetVariant( GetAllBlackboardDefs().UI_QuickSlotsData.consumableBeingUsed ) ) ); if( itemData ) { if( ItemID.IsValid( consumableBeingUsed ) && ( TweakDBInterface.GetConsumableItemRecord( ItemID.GetTDBID( itemData.GetID() ) ) == TweakDBInterface.GetConsumableItemRecord( ItemID.GetTDBID( consumableBeingUsed ) ) ) ) { return false; } CS = CraftingSystem.GetInstance( gameInstance ); return CS.CanItemBeDisassembled( itemData ); } return false; } public static function IsItemEquipped( owner : weak< GameObject >, itemID : ItemID ) : Bool { var ES : EquipmentSystem; var result : Bool; ES = EquipmentSystem.GetInstance( owner ); result = ES.IsEquipped( owner, itemID ); return result; } public static function IsItemCrafted( itemData : weak< gameItemData > ) : Bool { var value : Float; value = itemData.GetStatValueByType( gamedataStatType.IsItemCrafted ); return value > 0.0; } public static function IsItemCrafted( gi : GameInstance, itemId : ItemID ) : Bool { var value : Float; var statsID : StatsObjectID; statsID = ( ( StatsObjectID )( itemId ) ); value = GameInstance.GetStatsSystem( gi ).GetStatValue( statsID, gamedataStatType.IsItemCrafted ); return value > 0.0; } public static function ConsumeItem( obj : weak< GameObject >, evt : InteractionChoiceEvent ) : Bool { var itemQuantity : Int32; var lootActionWrapper : LootChoiceActionWrapper; var request : EquipmentSystemWeaponManipulationRequest; var eqs : EquipmentSystem; var blackboard : IBlackboard; var gameInstance : GameInstance; var transactionSystem : TransactionSystem; var itemType : gamedataItemType; lootActionWrapper = LootChoiceActionWrapper.Unwrap( evt ); gameInstance = obj.GetGame(); transactionSystem = GameInstance.GetTransactionSystem( gameInstance ); if( lootActionWrapper.action == 'Consume' ) { itemQuantity = GameInstance.GetTransactionSystem( gameInstance ).GetItemQuantity( obj, lootActionWrapper.itemId ); transactionSystem.TransferItem( obj, evt.activator, lootActionWrapper.itemId, itemQuantity ); itemType = GetItemType( lootActionWrapper.itemId ); if( itemType == gamedataItemType.Con_Inhaler || itemType == gamedataItemType.Con_Injector ) { blackboard = GameInstance.GetBlackboardSystem( gameInstance ).Get( GetAllBlackboardDefs().UI_QuickSlotsData ); blackboard.SetVariant( GetAllBlackboardDefs().UI_QuickSlotsData.containerConsumable, lootActionWrapper.itemId ); eqs = ( ( EquipmentSystem )( GameInstance.GetScriptableSystemsContainer( gameInstance ).Get( 'EquipmentSystem' ) ) ); request = new EquipmentSystemWeaponManipulationRequest; request.owner = evt.activator; request.requestType = EquipmentManipulationAction.RequestConsumable; eqs.QueueRequest( request ); } else { ItemActionsHelper.ConsumeItem( evt.activator, lootActionWrapper.itemId, true ); return true; } } else if( lootActionWrapper.action == 'Eat' ) { itemQuantity = GameInstance.GetTransactionSystem( gameInstance ).GetItemQuantity( obj, lootActionWrapper.itemId ); transactionSystem.TransferItem( obj, evt.activator, lootActionWrapper.itemId, itemQuantity ); ItemActionsHelper.EatItem( evt.activator, lootActionWrapper.itemId, true ); return true; } else if( lootActionWrapper.action == 'Drink' ) { itemQuantity = GameInstance.GetTransactionSystem( gameInstance ).GetItemQuantity( obj, lootActionWrapper.itemId ); transactionSystem.TransferItem( obj, evt.activator, lootActionWrapper.itemId, itemQuantity ); ItemActionsHelper.DrinkItem( evt.activator, lootActionWrapper.itemId, true ); return true; } return false; } public static function IsWeaponMelee( type : gamedataItemType ) : Bool { return ( ( ( ( ( ( ( ( ( ( type == gamedataItemType.Wea_Fists || type == gamedataItemType.Wea_Knife ) || type == gamedataItemType.Wea_Katana ) || type == gamedataItemType.Wea_Sword ) || type == gamedataItemType.Wea_OneHandedClub ) || type == gamedataItemType.Wea_LongBlade ) || type == gamedataItemType.Wea_ShortBlade ) || type == gamedataItemType.Wea_Melee ) || type == gamedataItemType.Wea_Axe ) || type == gamedataItemType.Wea_Chainsword ) || type == gamedataItemType.Wea_Machete ) || type == gamedataItemType.Wea_Hammer; } public static function BreakItem( gi : GameInstance, owner : GameObject, itemID : ItemID ) : Bool { var chance : Float; var rand : Float; var itemData : weak< gameItemData >; itemData = GameInstance.GetTransactionSystem( gi ).GetItemData( owner, itemID ); if( !( itemData ) ) { return false; } if( RPGManager.GetItemDataQuality( itemData ) == gamedataQuality.Common ) { chance = TDB.GetFloat( T"GlobalStats.ChanceForItemToBeBroken.value", 1.0 ); rand = RandF(); if( rand < chance ) { return true; } } return false; } public static function DropManyItems( gameInstance : GameInstance, obj : weak< GameObject >, const items : ref< array< ItemModParams > > ) { var i : Int32; var dropList : array< DropInstruction >; var LM : LootManager; for( i = 0; i < items.Size(); i += 1 ) { dropList.PushBack( DropInstruction.Create( items[ i ].itemID, items[ i ].quantity ) ); RPGManager.ReturnRetrievableWeaponMods( GetItemData( gameInstance, obj, items[ i ].itemID ), obj ); } LM = GameInstance.GetLootManager( gameInstance ); LM.SpawnItemDropOfManyItems( obj, dropList, 'playerDropBag', obj.GetWorldPosition() ); } public static function GetRandomizedHealingConsumable( puppet : weak< ScriptedPuppet > ) : TweakDBID { var rand : Int32; var list : array< TweakDBID >; list.PushBack( T"Items.FirstAidWhiffV0" ); list.PushBack( T"Items.BonesMcCoy70V0" ); rand = RandRange( 0, list.Size() + 1 ); return list[ rand ]; } public static function GetRandomizedGadget( puppet : weak< ScriptedPuppet > ) : TweakDBID { var rand : Int32; var list : array< TweakDBID >; rand = RandRange( 0, list.Size() + 1 ); return list[ rand ]; } public static function ForceUnequipItemFromPlayer( puppet : GameObject, slotTDBID : TweakDBID, removeItem : Bool ) { var itemID : ItemID; var transactionSys : TransactionSystem; if( ( puppet == NULL ) && !( ( ( PlayerPuppet )( puppet ) ) ) ) { return; } if( !( TDBID.IsValid( slotTDBID ) ) ) { return; } transactionSys = GameInstance.GetTransactionSystem( puppet.GetGame() ); itemID = transactionSys.GetItemInSlot( puppet, slotTDBID ).GetItemID(); transactionSys.RemoveItemFromSlot( puppet, slotTDBID, true ); if( removeItem ) { transactionSys.RemoveItem( puppet, itemID, 1 ); } } public static function ToggleHolsteredArmAppearance( puppet : GameObject, setHoleInArm : Bool ) { var itemObj : ItemObject; var player : PlayerPuppet; var switchEvent : gameuiPersonalLinkSwitcherEvent; player = ( ( PlayerPuppet )( puppet ) ); if( !( player ) ) { return; } switchEvent = new gameuiPersonalLinkSwitcherEvent; switchEvent.isAdvanced = setHoleInArm; itemObj = GameInstance.GetTransactionSystem( player.GetGame() ).GetItemInSlot( player, RPGManager.GetAttachmentSlotID( "RightArm" ) ); if( itemObj ) { itemObj.QueueEvent( switchEvent ); } } public static function TogglePersonalLinkAppearance( puppet : GameObject ) { var itemObj : ItemObject; var player : PlayerPuppet; var meshEvent : entAppearanceEvent; player = ( ( PlayerPuppet )( puppet ) ); if( !( player ) ) { return; } itemObj = GameInstance.GetTransactionSystem( player.GetGame() ).GetItemInSlot( player, RPGManager.GetAttachmentSlotID( "PersonalLink" ) ); if( ItemID.GetTDBID( EquipmentSystem.GetData( player ).GetActiveItem( gamedataEquipmentArea.RightArm ) ) == T"Items.HolsteredStrongArms" ) { meshEvent = new entAppearanceEvent; meshEvent.appearanceName = 'only_plug'; itemObj.QueueEvent( meshEvent ); return; } } public static function HasStatFlag( owner : weak< GameObject >, flag : gamedataStatType ) : Bool { if( !( owner ) || !( owner.IsAttached() ) ) { return false; } return GameInstance.GetStatsSystem( owner.GetGame() ).GetStatBoolValue( owner.GetEntityID(), flag ); } public static function DoesPlayerHaveQuickHack( player : weak< PlayerPuppet >, quickHackTweak : TweakDBID ) : Bool { var actionIDs : array< TweakDBID >; var i : Int32; actionIDs = GetPlayerQuickHackList( player ); for( i = 0; i < actionIDs.Size(); i += 1 ) { if( actionIDs[ i ] == quickHackTweak ) { return true; } } return false; } public static function GetPlayerQuickHackList( player : weak< PlayerPuppet > ) : array< TweakDBID > { var i : Int32; var actionIDs : array< TweakDBID >; var playerActions : array< PlayerQuickhackData >; playerActions = GetPlayerQuickHackListWithQuality( player ); for( i = 0; i < playerActions.Size(); i += 1 ) { actionIDs.PushBack( playerActions[ i ].actionRecord.GetID() ); } return actionIDs; } public static function GetPlayerQuickHackListWithQuality( player : weak< PlayerPuppet > ) : array< PlayerQuickhackData > { var systemReplacementID : ItemID; var parts : array< SPartSlots >; var i, i1 : Int32; var itemRecord : weak< Item_Record >; var itemID : ItemID; var tweakItemID : TweakDBID; var actions : array< weak< ObjectAction_Record > >; var quickhackDataArray : array< PlayerQuickhackData >; var quickhackData : PlayerQuickhackData; var quickhackDataEmpty : PlayerQuickhackData; quickhackDataArray = player.GetCachedQuickHackList(); if( quickhackDataArray.Size() > 0 ) { return quickhackDataArray; } systemReplacementID = EquipmentSystem.GetData( player ).GetActiveItem( gamedataEquipmentArea.SystemReplacementCW ); itemRecord = RPGManager.GetItemRecord( systemReplacementID ); tweakItemID = itemRecord.GetID(); if( EquipmentSystem.IsCyberdeckEquipped( player ) ) { itemRecord.ObjectActions( actions ); for( i = 0; i < actions.Size(); i += 1 ) { if( ( actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.DeviceQuickHack || actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.PuppetQuickHack ) || actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.VehicleQuickHack ) { quickhackData = quickhackDataEmpty; quickhackData.actionRecord = actions[ i ]; quickhackData.quality = itemRecord.Quality().Value(); quickhackDataArray.PushBack( quickhackData ); } } parts = ItemModificationSystem.GetAllSlots( player, systemReplacementID ); for( i = 0; i < parts.Size(); i += 1 ) { actions.Clear(); itemRecord = RPGManager.GetItemRecord( parts[ i ].installedPart ); tweakItemID = itemRecord.GetID(); itemID = ItemID.FromTDBID( tweakItemID ); if( itemRecord ) { itemRecord.ObjectActions( actions ); for( i1 = 0; i1 < actions.Size(); i1 += 1 ) { if( ( actions[ i1 ].ObjectActionType().Type() == gamedataObjectActionType.DeviceQuickHack || actions[ i1 ].ObjectActionType().Type() == gamedataObjectActionType.PuppetQuickHack ) || actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.VehicleQuickHack ) { quickhackData = quickhackDataEmpty; quickhackData.actionRecord = actions[ i1 ]; quickhackData.quality = itemRecord.Quality().Value(); quickhackData.itemID = itemID; quickhackDataArray.PushBack( quickhackData ); } } } } } actions.Clear(); itemRecord = RPGManager.GetItemRecord( EquipmentSystem.GetData( player ).GetActiveItem( gamedataEquipmentArea.Splinter ) ); if( itemRecord ) { itemRecord.ObjectActions( actions ); for( i = 0; i < actions.Size(); i += 1 ) { if( ( actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.DeviceQuickHack || actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.PuppetQuickHack ) || actions[ i ].ObjectActionType().Type() == gamedataObjectActionType.VehicleQuickHack ) { quickhackData = quickhackDataEmpty; quickhackData.actionRecord = actions[ i ]; quickhackDataArray.PushBack( quickhackData ); } } } RemoveDuplicatedHacks( quickhackDataArray ); PlayerPuppet.ChacheQuickHackList( player, quickhackDataArray ); return quickhackDataArray; } public static function GetMonoWireQuickhackRecord( weaponObject : WeaponObject ) : Item_Record { var quickhackSlotInnerData : InnerItemData; var selectedQuickhackItemID : ItemID; if( !( WeaponObject.IsOfType( weaponObject.GetItemID(), gamedataItemType.Cyb_NanoWires ) ) ) { return NULL; } weaponObject.GetItemData().GetItemPart( quickhackSlotInnerData, T"AttachmentSlots.NanoWiresQuickhackSlot" ); selectedQuickhackItemID = InnerItemData.GetItemID( quickhackSlotInnerData ); return GetItemRecord( selectedQuickhackItemID ); } public static function GetMonoWireQuickHackData( playerOwner : PlayerPuppet, targetScriptedPuppet : ScriptedPuppet, weaponObject : WeaponObject ) : QuickhackData { var monowireQuickHackData : QuickhackData; var quickhackRecordActions : array< weak< ObjectAction_Record > >; var selectedQuickhackActionRecord : ObjectAction_Record; var quickhackRecord : Item_Record; var context : GetActionsContext; var targetPuppetActions : array< PuppetAction >; var targetActionRecords : array< weak< ObjectAction_Record > >; var i : Int32; var j : Int32; var hasSameActionName : Bool; var isQuickhackOfDeviceOrPuppetType : Bool; var newActionHasBiggerPriority : Bool; quickhackRecord = GetMonoWireQuickhackRecord( weaponObject ); if( !( targetScriptedPuppet ) || !( quickhackRecord ) ) { return NULL; } context = targetScriptedPuppet.GetPuppetPS().GenerateContext( gamedeviceRequestType.Remote, Device.GetInteractionClearance(), playerOwner, targetScriptedPuppet.GetEntityID() ); targetScriptedPuppet.GetRecord().ObjectActions( targetActionRecords ); targetScriptedPuppet.GetPuppetPS().GetAllChoices( targetActionRecords, context, targetPuppetActions ); if( targetPuppetActions.Size() == 0 ) { return NULL; } quickhackRecord.ObjectActions( quickhackRecordActions ); selectedQuickhackActionRecord = NULL; for( i = 0; i < targetPuppetActions.Size(); i += 1 ) { for( j = quickhackRecordActions.Size() - 1; j >= 0; j -= 1 ) { hasSameActionName = quickhackRecordActions[ j ].ActionName() == targetPuppetActions[ i ].GetObjectActionRecord().ActionName(); isQuickhackOfDeviceOrPuppetType = quickhackRecordActions[ j ].ObjectActionType().Type() == gamedataObjectActionType.DeviceQuickHack || quickhackRecordActions[ j ].ObjectActionType().Type() == gamedataObjectActionType.PuppetQuickHack; if( hasSameActionName && isQuickhackOfDeviceOrPuppetType ) { if( !( selectedQuickhackActionRecord ) ) { selectedQuickhackActionRecord = quickhackRecordActions[ j ]; continue; } newActionHasBiggerPriority = quickhackRecordActions[ j ].Priority() > selectedQuickhackActionRecord.Priority(); if( newActionHasBiggerPriority ) { selectedQuickhackActionRecord = quickhackRecordActions[ j ]; } } } if( selectedQuickhackActionRecord ) { break; } } if( !( selectedQuickhackActionRecord ) ) { return NULL; } monowireQuickHackData = new QuickhackData; monowireQuickHackData.m_actionOwner = targetScriptedPuppet.GetEntityID(); monowireQuickHackData.m_actionOwnerName = StringToName( targetScriptedPuppet.GetTweakDBFullDisplayName( true ) ); monowireQuickHackData.m_action = targetPuppetActions[ i ]; monowireQuickHackData.m_uploadTime = targetPuppetActions[ i ].GetActivationTime(); monowireQuickHackData.m_duration = targetScriptedPuppet.GetQuickHackDurationFromLongestEffect( selectedQuickhackActionRecord, ( ( GameObject )( targetScriptedPuppet ) ), targetScriptedPuppet.GetEntityID(), playerOwner.GetEntityID() ); monowireQuickHackData.m_action.SetObjectActionID( selectedQuickhackActionRecord.GetID() ); monowireQuickHackData.m_cost = 0; monowireQuickHackData.m_title = LocKeyToString( selectedQuickhackActionRecord.ObjectActionUI().Caption() ); return monowireQuickHackData; } public static function CreateSimpleQuickhackData( playerOwner : PlayerPuppet, targetScriptedPuppet : ScriptedPuppet, quickhackActionRecord : ObjectAction_Record ) : QuickhackData { var monowireQuickHackData : QuickhackData; var context : GetActionsContext; var targetPuppetActions : array< PuppetAction >; var targetActionRecords : array< weak< ObjectAction_Record > >; var i : Int32; var quickHackActionFound : Bool; quickHackActionFound = false; context = targetScriptedPuppet.GetPuppetPS().GenerateContext( gamedeviceRequestType.Remote, Device.GetInteractionClearance(), playerOwner, targetScriptedPuppet.GetEntityID() ); targetScriptedPuppet.GetRecord().ObjectActions( targetActionRecords ); targetScriptedPuppet.GetPuppetPS().GetAllChoices( targetActionRecords, context, targetPuppetActions ); for( i = 0; i < targetPuppetActions.Size(); i += 1 ) { if( quickhackActionRecord.ActionName() == targetPuppetActions[ i ].GetObjectActionRecord().ActionName() ) { quickHackActionFound = true; break; } } if( !( quickHackActionFound ) ) { return NULL; } monowireQuickHackData = new QuickhackData; monowireQuickHackData.m_actionOwner = targetScriptedPuppet.GetEntityID(); monowireQuickHackData.m_actionOwnerName = StringToName( targetScriptedPuppet.GetTweakDBFullDisplayName( true ) ); monowireQuickHackData.m_action = targetPuppetActions[ i ]; monowireQuickHackData.m_uploadTime = targetPuppetActions[ i ].GetActivationTime(); monowireQuickHackData.m_duration = targetScriptedPuppet.GetQuickHackDurationFromLongestEffect( quickhackActionRecord, ( ( GameObject )( targetScriptedPuppet ) ), targetScriptedPuppet.GetEntityID(), playerOwner.GetEntityID() ); monowireQuickHackData.m_action.SetObjectActionID( quickhackActionRecord.GetID() ); monowireQuickHackData.m_cost = 0; return monowireQuickHackData; } public static function IncrementQuickHackBlackboard( gameInstance : GameInstance, actionID : TweakDBID ) { var playerPuppet : PlayerPuppet; var playerBlackboard : IBlackboard; var uploadingQuickHackIDs : array< TweakDBID >; playerPuppet = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( gameInstance ).GetLocalPlayerControlledGameObject() ) ); if( playerPuppet ) { playerBlackboard = GameInstance.GetBlackboardSystem( gameInstance ).GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); uploadingQuickHackIDs = ( ( array< TweakDBID > )( playerBlackboard.GetVariant( GetAllBlackboardDefs().PlayerStateMachine.UploadingQuickHackIDs ) ) ); uploadingQuickHackIDs.PushBack( actionID ); playerBlackboard.SetVariant( GetAllBlackboardDefs().PlayerStateMachine.UploadingQuickHackIDs, uploadingQuickHackIDs ); } } public static function DecrementQuickHackBlackboard( gameInstance : GameInstance, actionID : TweakDBID ) { var playerPuppet : PlayerPuppet; var playerBlackboard : IBlackboard; var uploadingQuickHackIDs : array< TweakDBID >; playerPuppet = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( gameInstance ).GetLocalPlayerControlledGameObject() ) ); if( playerPuppet ) { playerBlackboard = GameInstance.GetBlackboardSystem( gameInstance ).GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); uploadingQuickHackIDs = ( ( array< TweakDBID > )( playerBlackboard.GetVariant( GetAllBlackboardDefs().PlayerStateMachine.UploadingQuickHackIDs ) ) ); uploadingQuickHackIDs.Remove( actionID ); playerBlackboard.SetVariant( GetAllBlackboardDefs().PlayerStateMachine.UploadingQuickHackIDs, uploadingQuickHackIDs ); } } private static function RemoveDuplicatedHacks( commands : ref< array< PlayerQuickhackData > > ) { var i, i1 : Int32; var indexesToRemove : array< Int32 >; for( i = commands.Size() - 1; i >= 0; i -= 1 ) { for( i1 = 0; i1 < i; i1 += 1 ) { if( commands[ i ].actionRecord.ActionName() == commands[ i1 ].actionRecord.ActionName() && commands[ i ].actionRecord.ObjectActionType().Type() == commands[ i1 ].actionRecord.ObjectActionType().Type() ) { if( commands[ i ].actionRecord.Priority() >= commands[ i1 ].actionRecord.Priority() ) { if( !( indexesToRemove.Contains( i1 ) ) ) { indexesToRemove.PushBack( i1 ); } } else { if( !( indexesToRemove.Contains( i1 ) ) ) { indexesToRemove.PushBack( i1 ); } } } } } indexesToRemove = ArraySortReverse( indexesToRemove ); for( i = 0; i < indexesToRemove.Size(); i += 1 ) { commands.Erase( indexesToRemove[ i ] ); } } private static function RemoveDuplicatedHacks( deck : ref< array< weak< ObjectAction_Record > > >, splinter : ref< array< weak< ObjectAction_Record > > > ) { var i, i1 : Int32; for( i = deck.Size() - 1; i >= 0; i -= 1 ) { for( i1 = splinter.Size() - 1; i1 >= 0; i1 -= 1 ) { if( deck[ i ].ActionName() == splinter[ i1 ].ActionName() ) { if( deck[ i ].Priority() >= splinter[ i1 ].Priority() ) { splinter.Erase( i1 ); } else { deck.Erase( i ); } } } } } public static function GetPlayerCurrentHealthPercent( gi : GameInstance ) : Float { var player : weak< PlayerPuppet >; player = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( gi ).GetLocalPlayerControlledGameObject() ) ); if( player ) { return GameInstance.GetStatPoolsSystem( gi ).GetStatPoolValue( player.GetEntityID(), gamedataStatPoolType.Health, true ); } return -1.0; } public static function GetVendorWareRequirement( game : GameInstance, record : weak< VendorWare_Record >, itemStatsID : StatsObjectID ) : SItemStackRequirementData { var statPrereq : StatPrereq_Record; var data : SItemStackRequirementData; statPrereq = ( ( StatPrereq_Record )( record.AvailabilityPrereq() ) ); if( statPrereq ) { data.statType = ( ( gamedataStatType )( ( ( Int32 )( EnumValueFromName( 'gamedataStatType', statPrereq.StatType() ) ) ) ) ); if( StatsObjectID.IsDefined( itemStatsID ) && ( statPrereq.GetStatModifiersCount() > 0 ) ) { data.requiredValue = StatsSystemHelper.GetStatPrereqModifiersValue( game, itemStatsID, statPrereq.GetID() ); } else { data.requiredValue = statPrereq.ValueToCheck(); } } else { data.statType = gamedataStatType.Invalid; data.requiredValue = -1.0; } return data; } public static function CyberwareHasUpgrade( game : GameInstance, itemID : ItemID, currentQuality : gamedataQuality, desiredQuality : gamedataQuality, out upgradeItemRecord : Item_Record ) : Bool { var potentialUpgradeRecord : Item_Record; var confirmedUpgradeRecord : Item_Record; var qualityUpgrade : Int32; qualityUpgrade = ConvertQualityToCombinedValue( desiredQuality ) - ConvertQualityToCombinedValue( currentQuality ); potentialUpgradeRecord = RPGManager.GetItemRecord( itemID ).NextUpgradeItem(); while( qualityUpgrade >= 1 ) { if( TDBID.IsValid( potentialUpgradeRecord.GetID() ) ) { confirmedUpgradeRecord = potentialUpgradeRecord; potentialUpgradeRecord = confirmedUpgradeRecord.NextUpgradeItem(); } else { break; } qualityUpgrade -= 1; } if( TDBID.IsValid( confirmedUpgradeRecord.GetID() ) && ( qualityUpgrade <= 0 ) ) { upgradeItemRecord = confirmedUpgradeRecord; return true; } return false; } public static function CyberwareHasSideUpgrade( itemID : ItemID, out sideUpgradeItemRecord : Item_Record ) : Bool { var sideUpgradeRecord : Item_Record; sideUpgradeRecord = RPGManager.GetItemRecord( itemID ).SideUpgradeItem(); if( TDBID.IsValid( sideUpgradeRecord.GetID() ) ) { sideUpgradeItemRecord = sideUpgradeRecord; return true; } return false; } public static function CanUpgradeCyberware( owner : GameObject, itemID : ItemID, isEquipped : Bool, selectedQuality : gamedataQuality, out upgradeItemQuality : gamedataQuality, out upgradeItemRecord : Item_Record, out costData : CyberwareUpgradeCostData, optional updateOutputOnFailure : Bool ) : Bool { var game : GameInstance; var itemCombinedQualityValue, checkQualityValue : Int32; var potentialUpgradeQuality, currentItemQuality : gamedataQuality; var potentialUpgradeItemRecord : Item_Record; var potentialCostData : CyberwareUpgradeCostData; game = owner.GetGame(); if( !( isEquipped ) ) { return false; } itemCombinedQualityValue = GetCombinedItemQualityValue( game, itemID ); currentItemQuality = ConvertCombinedValueToQuality( itemCombinedQualityValue ); if( selectedQuality != gamedataQuality.Invalid ) { checkQualityValue = ConvertQualityToCombinedValue( selectedQuality ); } else { checkQualityValue = itemCombinedQualityValue + 1; } if( checkQualityValue <= ConvertQualityToCombinedValue( ( ( IsEP1() ) ? ( gamedataQuality.LegendaryPlusPlus ) : ( gamedataQuality.LegendaryPlus ) ) ) ) { potentialUpgradeQuality = ConvertCombinedValueToQuality( checkQualityValue ); if( CyberwareHasUpgrade( game, itemID, currentItemQuality, potentialUpgradeQuality, potentialUpgradeItemRecord ) ) { if( CanAffordAndPerformCyberwareUpgrade( owner, currentItemQuality, potentialUpgradeItemRecord, potentialCostData ) ) { upgradeItemRecord = potentialUpgradeItemRecord; upgradeItemQuality = potentialUpgradeQuality; costData = potentialCostData; return true; } } } if( updateOutputOnFailure ) { upgradeItemRecord = potentialUpgradeItemRecord; upgradeItemQuality = potentialUpgradeQuality; costData = potentialCostData; } return false; } public static function CanAffordAndPerformCyberwareUpgrade( owner : GameObject, currentQuality : gamedataQuality, upgradeItemRecord : Item_Record, out costData : CyberwareUpgradeCostData ) : Bool { var currentItemPlusValue, upgradeItemPlusValue : Int32; var currentNonPlusQuality, upgradeNonPlusQuality, newQuality : gamedataQuality; var upgradeIsValid : Bool; newQuality = upgradeItemRecord.QualityHandle().Type(); upgradeItemPlusValue = ConvertQualityToItemPlusValue( newQuality ); upgradeNonPlusQuality = ConvertQualityToNonPlusQuality( newQuality ); if( upgradeItemPlusValue > 0 ) { currentItemPlusValue = ConvertQualityToItemPlusValue( currentQuality ); currentNonPlusQuality = ConvertQualityToNonPlusQuality( currentQuality ); if( currentNonPlusQuality == upgradeNonPlusQuality && ( ( upgradeItemPlusValue - currentItemPlusValue ) == 1 ) ) { upgradeIsValid = true; } } else { upgradeIsValid = true; } if( upgradeIsValid ) { costData.materialRecordID = GetCraftingMaterialRecord( upgradeNonPlusQuality ).GetID(); costData.materialCount = GetCyberwareUpgradeCost( upgradeItemRecord ); if( GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemQuantityWithDuplicates( owner, ItemID.CreateQuery( costData.materialRecordID ) ) >= costData.materialCount ) { return true; } } return false; } public static function GetCyberwareUpgradeCost( itemRecord : Item_Record ) : Int32 { var baseCost : Float; var quality : gamedataQuality; var coreCW : Bool; quality = itemRecord.QualityHandle().Type(); coreCW = itemRecord.IsCoreCW(); switch( quality ) { case gamedataQuality.CommonPlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.commonPlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.commonPlus" ); } break; case gamedataQuality.Uncommon: baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.uncommon" ); break; case gamedataQuality.UncommonPlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.uncommonPlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.uncommonPlus" ); } break; case gamedataQuality.Rare: baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.rare" ); break; case gamedataQuality.RarePlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.rarePlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.rarePlus" ); } break; case gamedataQuality.Epic: baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.epic" ); break; case gamedataQuality.EpicPlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.epicPlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.epicPlus" ); } break; case gamedataQuality.Legendary: baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.legendary" ); break; case gamedataQuality.LegendaryPlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.legendaryPlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.legendaryPlus" ); } break; case gamedataQuality.LegendaryPlusPlus: if( coreCW ) { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.legendaryPlusPlus_CoreCW" ); } else { baseCost = TDB.GetFloat( T"Items.CyberwareBaseUpgradeCosts.legendaryPlusPlus" ); } break; default: return 0; } return ( ( Int32 )( itemRecord.UpgradeCostMult() * baseCost ) ); } public static function GetCyberwareUpgradeShardCount( owner : GameObject, quality : gamedataQuality ) : Int32 { return GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemQuantityWithDuplicates( owner, ItemID.CreateQuery( GetCyberwareUpgradeShardID( quality ) ) ); } public static function GetCyberwareUpgradeShardItemData( owner : GameObject, quality : gamedataQuality ) : weak< gameItemData > { return GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemDataByTDBID( owner, GetCyberwareUpgradeShardID( quality ) ); } public static function GetCyberwareUpgradeShardID( quality : gamedataQuality ) : TweakDBID { var requiredShardID : TweakDBID; switch( quality ) { case gamedataQuality.Uncommon: requiredShardID = T"Items.CyberwareUpgradeShardUncommon"; break; case gamedataQuality.Rare: requiredShardID = T"Items.CyberwareUpgradeShardRare"; break; case gamedataQuality.Epic: requiredShardID = T"Items.CyberwareUpgradeShardEpic"; break; case gamedataQuality.Legendary: requiredShardID = T"Items.CyberwareUpgradeShardLegendary"; break; default: requiredShardID = T"Items.CyberwareUpgradeShard"; break; } return requiredShardID; } public static function ShouldShowCWChoice( owner : GameObject, itemData : weak< UIInventoryItem > ) : Bool { var playerDevelopmentData : PlayerDevelopmentData; playerDevelopmentData = PlayerDevelopmentSystem.GetData( owner ); return playerDevelopmentData.IsNewPerkBoughtAnyLevel( gamedataNewPerkType.Tech_Inbetween_Right_2 ) && itemData.GetEquipmentArea() != gamedataEquipmentArea.SystemReplacementCW; } private static function GetCyberwareUpgradeItemDataWithOffset( owner : GameObject, upgradeItemRecord : Item_Record, statsShardTDBID : TweakDBID, seed : Uint32, offset : Int32 ) : gameItemData { var statsShardItemID : ItemID; var optionId : ItemID; var newItemModParams : ItemModParams; optionId = ItemID.FromTDBID( upgradeItemRecord.GetID() ); newItemModParams.itemID = optionId; statsShardItemID = ItemID.CreateFromSeedWithOffset( statsShardTDBID, seed, offset ); newItemModParams.customPartsToInstall.PushBack( statsShardItemID ); return Inventory.CreateItemData( newItemModParams, owner ); } public static function GetCyberwareUpgradeData( owner : GameObject, itemData : weak< UIInventoryItem >, upgradeItemRecord : Item_Record, costData : CyberwareUpgradeCostData, seed : Uint32, inventorySystem : weak< UIInventoryScriptableSystem >, useMultichoice : Bool ) : RipperdocTokenPopupData { var data : RipperdocTokenPopupData; var newItemModParams : ItemModParams; var statsShardTDBID, statsShardSlotTDBID : TweakDBID; var existingStatsShard : InnerItemData; var statsShardItemID : ItemID; var upgradeQualityValue : Int32; var sideItemModParams : ItemModParams; var useSideItem : Bool; data = new RipperdocTokenPopupData; data.notificationName = 'base\gameplay\gui\widgets\notifications\ripperdoc_token_popup.inkwidget'; data.isBlocking = true; data.useCursor = true; data.costData = costData; data.queueName = 'modal_popup'; upgradeQualityValue = upgradeItemRecord.QualityHandle().Value(); if( upgradeQualityValue >= 8 ) { statsShardTDBID = T"Items.CyberwareStatsShardLegendary"; } else if( upgradeQualityValue >= 6 ) { statsShardTDBID = T"Items.CyberwareStatsShardEpic"; } else if( upgradeQualityValue >= 4 ) { statsShardTDBID = T"Items.CyberwareStatsShardRare"; } else if( upgradeQualityValue >= 2 ) { statsShardTDBID = T"Items.CyberwareStatsShardUncommon"; } else { statsShardTDBID = T"Items.CyberwareStatsShardCommon"; } statsShardSlotTDBID = T"AttachmentSlots.StatsShardSlot"; newItemModParams.itemID = ItemID.FromTDBID( upgradeItemRecord.GetID() ); newItemModParams.quantity = 1; if( itemData.GetItemData().HasPartInSlot( statsShardSlotTDBID ) ) { itemData.GetItemData().GetItemPart( existingStatsShard, statsShardSlotTDBID ); statsShardItemID = ItemID.DuplicateRandomSeedWithOffset( InnerItemData.GetItemID( existingStatsShard ), InnerItemData.GetStaticData( existingStatsShard ).GetRecordID(), 0 ); newItemModParams.customPartsToInstall.PushBack( statsShardItemID ); } useSideItem = PlayerDevelopmentSystem.GetData( GetPlayer( owner.GetGame() ) ).IsNewPerkBought( gamedataNewPerkType.Tech_Central_Milestone_3 ) >= 3; useSideItem = useSideItem && upgradeItemRecord.EquipAreaHandle().Type() == gamedataEquipmentArea.MusculoskeletalSystemCW; if( useSideItem ) { sideItemModParams.itemID = ItemID.FromTDBID( upgradeItemRecord.SideUpgradeItemHandle().GetID() ); sideItemModParams.customPartsToInstall.PushBack( statsShardItemID ); sideItemModParams.quantity = 1; data.option1SideItemData = Inventory.CreateItemData( sideItemModParams, owner ); data.option2SideItemData = GetCyberwareUpgradeItemDataWithOffset( owner, upgradeItemRecord.SideUpgradeItemHandle(), statsShardTDBID, seed, 1 ); data.option3SideItemData = GetCyberwareUpgradeItemDataWithOffset( owner, upgradeItemRecord.SideUpgradeItemHandle(), statsShardTDBID, seed, 2 ); } data.option1GameItemData = Inventory.CreateItemData( newItemModParams, owner ); data.option1InventoryItem = UIInventoryItem.Make( owner, ( ( useSideItem ) ? ( data.option1SideItemData ) : ( data.option1GameItemData ) ), inventorySystem.GetInventoryItemsManager() ); if( useMultichoice ) { data.option2GameItemData = GetCyberwareUpgradeItemDataWithOffset( owner, upgradeItemRecord, statsShardTDBID, seed, 1 ); data.option2InventoryItem = UIInventoryItem.Make( owner, ( ( useSideItem ) ? ( data.option2SideItemData ) : ( data.option2GameItemData ) ), inventorySystem.GetInventoryItemsManager() ); if( upgradeQualityValue >= 4 ) { data.option3GameItemData = GetCyberwareUpgradeItemDataWithOffset( owner, upgradeItemRecord, statsShardTDBID, seed, 2 ); data.option3InventoryItem = UIInventoryItem.Make( owner, ( ( useSideItem ) ? ( data.option3SideItemData ) : ( data.option3GameItemData ) ), inventorySystem.GetInventoryItemsManager() ); } } data.baseItemData = itemData; return data; } public static function CreateReplaceEquipmentRequest( owner : GameObject, equippedItemID : ItemID, upgradeItemID : ItemID, optional partItemID : ItemID ) { var replaceEquipmentRequest : ReplaceEquipmentRequest; var equipmentSystem : EquipmentSystem; equipmentSystem = ( ( EquipmentSystem )( GameInstance.GetScriptableSystemsContainer( owner.GetGame() ).Get( 'EquipmentSystem' ) ) ); replaceEquipmentRequest = new ReplaceEquipmentRequest; replaceEquipmentRequest.owner = owner; replaceEquipmentRequest.slotIndex = equipmentSystem.GetItemSlotIndex( owner, equippedItemID ); replaceEquipmentRequest.itemID = upgradeItemID; replaceEquipmentRequest.addToInventory = true; replaceEquipmentRequest.rerollIdOnAddToInventory = false; replaceEquipmentRequest.removeOldItem = true; replaceEquipmentRequest.customPartToGenerateID = partItemID; replaceEquipmentRequest.transferInstalledParts = true; equipmentSystem.QueueRequest( replaceEquipmentRequest ); } public static function HandleBuyShardPopupClosed( owner : GameObject, equippedItemId : ItemID, resultData : RipperdocTokenPopupCloseData ) { var statsShardItemID : ItemID; var statsShardData : InnerItemData; var statsShardSlotTDBID : TweakDBID; if( resultData.confirm ) { statsShardSlotTDBID = T"AttachmentSlots.StatsShardSlot"; if( resultData.chosenOptionData.HasPartInSlot( statsShardSlotTDBID ) ) { resultData.chosenOptionData.GetItemPart( statsShardData, statsShardSlotTDBID ); statsShardItemID = InnerItemData.GetItemID( statsShardData ); } CreateReplaceEquipmentRequest( owner, equippedItemId, resultData.chosenOptionData.GetID(), statsShardItemID ); GameInstance.GetTransactionSystem( owner.GetGame() ).RemoveItemByTDBID( owner, resultData.costData.materialRecordID, resultData.costData.materialCount ); GameInstance.GetInventoryManager( owner.GetGame() ).IncrementCyberwareUpgradeSeed( 3 ); } } public static function IsItemEffectivelyIdentical( itemID1 : ItemID, itemID2 : ItemID ) : Bool { if( ( ItemID.GetTDBID( itemID1 ) == ItemID.GetTDBID( itemID2 ) ) && ( ItemID.GetRngSeed( itemID1 ) == ItemID.GetRngSeed( itemID2 ) ) ) { return true; } return false; } public static function HealPuppetAfterQuickhack( gi : GameInstance, executor : GameObject ) { var statSystem : StatsSystem; statSystem = GameInstance.GetStatsSystem( gi ); if( statSystem.GetStatBoolValue( ( ( ScriptedPuppet )( executor ) ).GetEntityID(), gamedataStatType.CanQuickhackHealPuppet ) ) { GameInstance.GetStatusEffectSystem( gi ).ApplyStatusEffect( ( ( ScriptedPuppet )( executor ) ).GetEntityID(), T"BaseStatusEffect.QuickhackConsumableHealing" ); } } public static function ForceEquipStrongArms( player : PlayerPuppet, instantStatChange : Bool ) : Bool { var TS : TransactionSystem; var armsCW : ItemID; var record : WeaponItem_Record; var itemData : gameItemData; if( !( player ) ) { return false; } TS = GameInstance.GetTransactionSystem( player.GetGame() ); armsCW = EquipmentSystem.GetData( player ).GetActiveItem( gamedataEquipmentArea.ArmsCW ); if( !( TS ) || !( ItemID.IsValid( armsCW ) ) ) { return false; } record = TweakDBInterface.GetWeaponItemRecord( ItemID.GetTDBID( armsCW ) ); if( record && record.ItemType().Type() == gamedataItemType.Cyb_StrongArms ) { if( TS.IsSlotEmpty( player, T"AttachmentSlots.WeaponRight" ) && !( TS.IsSlotEmpty( player, T"AttachmentSlots.RightArm" ) ) ) { if( instantStatChange ) { EquipmentSystemPlayerData.UpdateArmSlot( player, armsCW, false ); itemData = RPGManager.GetItemData( player.GetGame(), player, armsCW ); itemData.AddStatsOnEquip( player ); } TS.AddItemToSlot( player, T"AttachmentSlots.RightArm", armsCW ); return true; } } return false; } public static function ForceUnequipStrongArms( player : PlayerPuppet ) : Bool { var TS : TransactionSystem; var armsCW : ItemID; var record : WeaponItem_Record; if( !( player ) ) { return false; } TS = GameInstance.GetTransactionSystem( player.GetGame() ); armsCW = EquipmentSystem.GetData( player ).GetActiveItem( gamedataEquipmentArea.ArmsCW ); if( !( TS ) || !( ItemID.IsValid( armsCW ) ) ) { return false; } record = TweakDBInterface.GetWeaponItemRecord( ItemID.GetTDBID( armsCW ) ); if( record && record.ItemType().Type() == gamedataItemType.Cyb_StrongArms ) { EquipmentSystemPlayerData.UpdateArmSlot( player, armsCW, true ); return true; } return false; } public static function ForceEquipPersonalLink( player : PlayerPuppet ) : Bool { var TS : TransactionSystem; var itemID : ItemID; var playerStateMachineBlackboard : IBlackboard; var playerPuppet : weak< PlayerPuppet >; if( !( player ) ) { return false; } TS = GameInstance.GetTransactionSystem( player.GetGame() ); itemID = ItemID.CreateQuery( T"Items.personal_link" ); if( !( TS ) || !( ItemID.IsValid( itemID ) ) ) { return false; } if( !( TS.HasItem( player, itemID ) ) ) { TS.GiveItem( player, itemID, 1 ); } TS.RemoveItemFromSlot( player, T"AttachmentSlots.PersonalLink" ); TS.AddItemToSlot( player, T"AttachmentSlots.PersonalLink", itemID ); playerPuppet = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( player.GetGame() ).GetLocalPlayerControlledGameObject() ) ); playerStateMachineBlackboard = GameInstance.GetBlackboardSystem( player.GetGame() ).GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); playerStateMachineBlackboard.SetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingViaPersonalLink, true ); return true; } public static function ForceUnequipPersonalLink( player : PlayerPuppet ) : Bool { var TS : TransactionSystem; var playerStateMachineBlackboard : IBlackboard; var playerPuppet : weak< PlayerPuppet >; if( !( player ) ) { return false; } TS = GameInstance.GetTransactionSystem( player.GetGame() ); if( !( TS ) ) { return false; } TS.RemoveItemFromSlot( player, T"AttachmentSlots.PersonalLink" ); playerPuppet = ( ( PlayerPuppet )( GameInstance.GetPlayerSystem( player.GetGame() ).GetLocalPlayerControlledGameObject() ) ); playerStateMachineBlackboard = GameInstance.GetBlackboardSystem( player.GetGame() ).GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); playerStateMachineBlackboard.SetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingViaPersonalLink, false ); return true; } } abstract class MathHelper { public constexpr static function PositiveInfinity() : Float { return 100000000.0; } public constexpr static function NegativeInfinity() : Float { return -100000000.0; } public constexpr static function EulerNumber() : Float { return 2.71828175; } public static function IsFloatInRange( value : Float, min : Float, max : Float, optional leftClosed : Bool, optional rightClosed : Bool ) : Bool { if( leftClosed && rightClosed ) { return ( value >= min ) && ( value <= max ); } if( leftClosed && !( rightClosed ) ) { return ( value >= min ) && ( value < max ); } if( !( leftClosed ) && rightClosed ) { return ( value > min ) && ( value <= max ); } return ( value > min ) && ( value < max ); } public static function NormalizeF( value : Float, min : Float, max : Float ) : Float { var numerator : Float; var denominator : Float; numerator = value - min; denominator = max - min; return numerator / denominator; } public static function RandFromNormalDist( optional mean : Float, optional stdDev : Float ) : Float { var output : Float; var uniform1, uniform2 : Float; var randStandardNormal : Float; if( stdDev == 0.0 ) { stdDev = 1.0; } uniform1 = RandF(); uniform2 = RandF(); randStandardNormal = SqrtF( -2.0 * LogF( uniform1 ) ) * CosF( ( 2.0 * Pi() ) * uniform2 ); output = ( randStandardNormal * stdDev ) + mean; return output; } } class StatusEffectTriggerListener extends CustomValueStatPoolsListener { var m_owner : weak< GameObject >; var m_statusEffect : TweakDBID; var m_statPoolType : gamedataStatPoolType; var m_instigator : weak< GameObject >; protected event OnStatPoolMinValueReached( value : Float ) { var puppet : ScriptedPuppet; var gameInstance : GameInstance; puppet = ( ( ScriptedPuppet )( m_owner ) ); if( puppet ) { gameInstance = puppet.GetGame(); GameInstance.GetStatusEffectSystem( gameInstance ).ApplyStatusEffect( puppet.GetEntityID(), m_statusEffect, GameObject.GetTDBID( m_instigator ), m_instigator.GetEntityID() ); GameInstance.GetStatPoolsSystem( gameInstance ).RequestRemovingStatPool( puppet.GetEntityID(), m_statPoolType ); GameObject.RemoveStatusEffectTriggerListener( puppet, this ); } } } class PhoneCallUploadDurationListener extends CustomValueStatPoolsListener { var m_gameInstance : GameInstance; var m_requesterPuppet : weak< ScriptedPuppet >; var m_requesterID : EntityID; var m_duration : Float; var m_statPoolType : gamedataStatPoolType; default m_statPoolType = gamedataStatPoolType.PhoneCallDuration; protected event OnStatPoolAdded() { SendUploadStartedEvent(); SetRegenBehavior(); } protected virtual function SetRegenBehavior() { var activationTime : Float; var regenMod : StatPoolModifier; activationTime = m_duration; regenMod.enabled = true; regenMod.valuePerSec = 100.0 / activationTime; regenMod.rangeEnd = 100.0; GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestSettingModifier( m_requesterID, m_statPoolType, gameStatPoolModificationTypes.Regeneration, regenMod ); } protected event OnStatPoolRemoved() { SendUploadFinishedEvent(); UnregisterListener(); } protected event OnStatPoolMaxValueReached( value : Float ) { if( m_statPoolType == gamedataStatPoolType.CallReinforcementProgress ) { m_requesterPuppet.GetPuppetStateBlackboard().SetBool( GetAllBlackboardDefs().PuppetState.HasCalledReinforcements, true ); } SendUploadFinishedEvent(); UnregisterListener(); } private function UnregisterListener() { GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestUnregisteringListener( m_requesterID, m_statPoolType, this ); } private function SendUploadStartedEvent() { var evt : UploadProgramProgressEvent; evt = new UploadProgramProgressEvent; evt.state = EUploadProgramState.STARTED; evt.duration = m_duration; evt.progressBarType = EProgressBarType.UPLOAD; evt.progressBarContext = EProgressBarContext.PhoneCall; evt.iconRecord = TweakDBInterface.GetChoiceCaptionIconPartRecord( T"ChoiceCaptionParts.PhoneCall" ); evt.statPoolType = m_statPoolType; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_requesterID, evt ); } protected function SendUploadFinishedEvent() { var evt : UploadProgramProgressEvent; evt = new UploadProgramProgressEvent; evt.state = EUploadProgramState.COMPLETED; evt.progressBarContext = EProgressBarContext.PhoneCall; evt.statPoolType = m_statPoolType; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_requesterID, evt ); } } class ActionUploadListener extends CustomValueStatPoolsListener { var m_action : ScriptableDeviceAction; var m_gameInstance : GameInstance; } class QuickHackDurationListener extends ActionUploadListener { protected event OnStatPoolAdded() { SendUploadStartedEvent( m_action ); SetRegenBehavior(); } protected virtual function SetRegenBehavior() { var activationTime : Float; var regenMod : StatPoolModifier; activationTime = m_action.GetDurationValue(); regenMod.enabled = true; regenMod.valuePerSec = 100.0 / activationTime; regenMod.rangeEnd = 100.0; GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestSettingModifier( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackDuration, gameStatPoolModificationTypes.Regeneration, regenMod ); } protected event OnStatPoolMaxValueReached( value : Float ) { m_action.CompleteAction( m_gameInstance ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestRemovingStatPool( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackDuration ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestUnregisteringListener( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackDuration, this ); SendUploadFinishedEvent(); } protected virtual function SendUploadStartedEvent( action : ScriptableDeviceAction ) { var evt : UploadProgramProgressEvent; var uploadDuration : Float; evt = new UploadProgramProgressEvent; uploadDuration = m_action.GetDurationValue(); evt.state = EUploadProgramState.STARTED; evt.duration = uploadDuration; evt.progressBarType = EProgressBarType.DURATION; evt.action = action; evt.iconRecord = action.GetInteractionIcon(); evt.statPoolType = gamedataStatPoolType.QuickHackDuration; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), evt ); } protected function SendUploadFinishedEvent() { var evt : UploadProgramProgressEvent; evt = new UploadProgramProgressEvent; evt.state = EUploadProgramState.COMPLETED; evt.action = m_action; evt.statPoolType = gamedataStatPoolType.QuickHackDuration; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), evt ); } } class QuickHackUploadListener extends ActionUploadListener { public virtual function Initialize() {} protected event OnStatPoolAdded() { var psmBB : IBlackboard; var enableQHSoundActivation : Bool; enableQHSoundActivation = true; if( m_action.IsQuickHack() ) { SendUploadStartedEvent( m_action ); psmBB = GameInstance.GetBlackboardSystem( m_gameInstance ).GetLocalInstanced( m_action.GetExecutor().GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); if( psmBB ) { enableQHSoundActivation = psmBB.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vision ) == ( ( Int32 )( gamePSMVision.Focus ) ); } if( enableQHSoundActivation ) { PlayQuickHackSound( 'ui_focus_mode_scanning_qh' ); } } SetRegenBehavior(); } protected virtual function SetRegenBehavior() { var activationTime : Float; var regenMod : StatPoolModifier; activationTime = m_action.GetActivationTime(); regenMod.enabled = true; regenMod.valuePerSec = 100.0 / activationTime; regenMod.rangeEnd = 100.0; GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestSettingModifier( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload, gameStatPoolModificationTypes.Regeneration, regenMod ); } protected event OnStatPoolMaxValueReached( value : Float ) { m_action.CompleteAction( m_gameInstance ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestRemovingStatPool( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestUnregisteringListener( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload, this ); if( m_action.IsQuickHack() ) { SendUploadFinishedEvent(); } } protected virtual function SendUploadStartedEvent( action : ScriptableDeviceAction ) { var evt : UploadProgramProgressEvent; var uploadDuration : Float; evt = new UploadProgramProgressEvent; uploadDuration = m_action.GetActivationTime(); evt.state = EUploadProgramState.STARTED; evt.duration = uploadDuration; evt.progressBarType = EProgressBarType.UPLOAD; evt.action = action; evt.iconRecord = action.GetInteractionIcon(); evt.statPoolType = gamedataStatPoolType.QuickHackUpload; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), evt ); QuickhackModule.RequestRefreshQuickhackMenu( m_gameInstance, m_action.GetRequesterID() ); } protected function SendUploadFinishedEvent() { var evt : UploadProgramProgressEvent; evt = new UploadProgramProgressEvent; evt.state = EUploadProgramState.COMPLETED; evt.action = m_action; if( m_action.m_isActionQueueingUsed ) { evt.deviceActionQueue = m_action.m_deviceActionQueue; } evt.statPoolType = gamedataStatPoolType.QuickHackUpload; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), evt ); PlayQuickHackSound( 'ui_focus_mode_scanning_qh_done' ); if( m_action.GetExecutor().IsPlayer() ) { RPGManager.DecrementQuickHackBlackboard( m_gameInstance, m_action.GetObjectActionID() ); } } protected function PlayQuickHackSound( eventName : CName ) { var flag : audioAudioEventFlags; flag = audioAudioEventFlags.Unique; GameObject.PlaySoundEventWithParams( m_action.GetExecutor(), eventName, flag ); } protected function RemoveLink( owner : weak< ScriptedPuppet > ) { var evt : RemoveLinkEvent; if( !( owner ) ) { return; } evt = new RemoveLinkEvent; owner.QueueEvent( evt ); } protected function RemoveLinkedStatusEffects( owner : weak< ScriptedPuppet >, optional ssAction : Bool ) { var evt : RemoveLinkedStatusEffectsEvent; if( !( owner ) ) { return; } evt = new RemoveLinkedStatusEffectsEvent; evt.ssAction = ssAction; owner.QueueEvent( evt ); } } class AccessBreachListener extends QuickHackUploadListener { } class UploadFromNPCToNPCListener extends QuickHackUploadListener { var m_npcPuppet : weak< ScriptedPuppet >; public override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float ) { var uploadEvent : UploadProgramProgressEvent; if( !( NPCPuppet.IsActive( m_npcPuppet ) ) ) { RemoveLinkedStatusEffects( m_npcPuppet ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestRemovingStatPool( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestUnregisteringListener( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload, this ); uploadEvent = new UploadProgramProgressEvent; uploadEvent.state = EUploadProgramState.COMPLETED; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), uploadEvent ); } } } class UploadFromNPCToPlayerListener extends QuickHackUploadListener { var m_playerPuppet : weak< ScriptedPuppet >; var m_npcPuppet : weak< ScriptedPuppet >; var m_npcSquad : array< EntityID >; var m_HUDData : HUDProgressBarData; var m_hudBlackboard : weak< IBlackboard >; private var m_startUploadTimeStamp : Float; private var m_ssAction : Bool; private var m_preventionHackLoopAction : Bool; private var m_shouldStopRevealOnPreventionDeescalation : Bool; private var m_squadScriptInterface : SquadScriptInterface; private var m_useInterruptionPrereqs : Bool; public override function Initialize() { var isPositionReveal : Bool; var isPreventionPositionReveal : Bool; var tbid : TweakDBID; tbid = m_action.GetObjectActionID(); isPositionReveal = tbid == T"AIQuickHack.HackRevealPosition"; isPreventionPositionReveal = m_action.GetObjectActionID() == T"AIQuickHack.PreventionHackRevealPosition"; m_useInterruptionPrereqs = m_action.GetObjectActionRecord().GetInterruptionPrereqsCount() > 0; m_hudBlackboard = GameInstance.GetBlackboardSystem( m_gameInstance ).Get( GetAllBlackboardDefs().UI_HUDProgressBar ); if( isPositionReveal || isPreventionPositionReveal ) { m_ssAction = true; m_shouldStopRevealOnPreventionDeescalation = isPreventionPositionReveal; AISquadHelper.GetSquadmatesID( m_npcPuppet, m_npcSquad ); AISquadHelper.GetSquadMemberInterface( m_npcPuppet, m_squadScriptInterface ); } else if( ( ( m_action.GetObjectActionID() == T"AIQuickHack.PreventionSystemHackerLoop" ) || ( m_action.GetObjectActionID() == T"AIQuickHack.PreventionSystemHackerLoop2" ) ) || ( m_action.GetObjectActionID() == T"AIQuickHack.PreventionSystemHackerLoop3" ) ) { m_preventionHackLoopAction = true; } } protected event OnStatPoolAdded() { SendUploadStartedEvent( m_action ); SaveLocksManager.RequestSaveLockAdd( m_playerPuppet.GetGame(), 'PlayerBeingHacked' ); } protected override function SendUploadStartedEvent( action : ScriptableDeviceAction ) { var isQuickhackPanelOpen : Bool; m_HUDData.active = true; m_HUDData.header = LocKeyToString( action.GetObjectActionRecord().ObjectActionUI().Caption() ); if( m_preventionHackLoopAction ) { m_HUDData.bottomText = "LocKey#22169"; m_HUDData.failedText = "LocKey#92701"; m_HUDData.completedText = "LocKey#92701"; m_HUDData.type = SimpleMessageType.Vehicle; } m_startUploadTimeStamp = EngineTime.ToFloat( GameInstance.GetSimTime( m_npcPuppet.GetGame() ) ); m_hudBlackboard.SetBool( GetAllBlackboardDefs().UI_HUDProgressBar.Active, m_HUDData.active ); m_hudBlackboard.SetString( GetAllBlackboardDefs().UI_HUDProgressBar.Header, m_HUDData.header ); m_hudBlackboard.SetString( GetAllBlackboardDefs().UI_HUDProgressBar.BottomText, m_HUDData.bottomText, true ); m_hudBlackboard.SetString( GetAllBlackboardDefs().UI_HUDProgressBar.FailedText, m_HUDData.failedText, true ); m_hudBlackboard.SetString( GetAllBlackboardDefs().UI_HUDProgressBar.CompletedText, m_HUDData.completedText, true ); m_hudBlackboard.SetVariant( GetAllBlackboardDefs().UI_HUDProgressBar.MessageType, m_HUDData.type, true ); isQuickhackPanelOpen = GameInstance.GetBlackboardSystem( m_gameInstance ).Get( GetAllBlackboardDefs().UI_QuickSlotsData ).GetBool( GetAllBlackboardDefs().UI_QuickSlotsData.quickhackPanelOpen ); if( isQuickhackPanelOpen ) { GameInstance.GetDelaySystem( m_gameInstance ).DelayEventNextFrame( m_playerPuppet, new RefreshQuickhackMenuEvent ); } } public function ForceClose() { OnStatPoolMaxValueReached( 100.0 ); } private function TryStartCombat( player : weak< ScriptedPuppet >, npc : weak< ScriptedPuppet >, targetTracker : weak< TargetTrackingExtension > ) { if( AIActionHelper.TryChangingAttitudeToHostile( npc, player ) ) { targetTracker.AddThreat( player, true, player.GetWorldPosition(), 1.0, -1.0, false ); m_npcPuppet.TriggerSecuritySystemNotification( player.GetWorldPosition(), player, ESecurityNotificationType.COMBAT ); } } protected event OnStatPoolMaxValueReached( value : Float ) { var actionEffects : array< weak< ObjectActionEffect_Record > >; var targetTracker : weak< TargetTrackingExtension >; var i : Int32; if( m_preventionHackLoopAction && PreventionSystemHackerLoop.KeepProgressBarAliveAfterCompletion( m_gameInstance ) ) { return false; } PreventionSystemHackerLoop.UpdateOtherProgressBarReference( m_gameInstance, NULL ); super.OnStatPoolMaxValueReached( value ); RemoveLink( m_npcPuppet ); ScriptedPuppet.SendActionSignal( m_npcPuppet, 'HackingCompleted', 1.0 ); m_HUDData.active = false; m_hudBlackboard.SetBool( GetAllBlackboardDefs().UI_HUDProgressBar.Active, m_HUDData.active ); m_action.GetObjectActionRecord().CompletionEffects( actionEffects ); m_npcPuppet.AddLinkedStatusEffect( m_npcPuppet.GetEntityID(), m_playerPuppet.GetEntityID(), actionEffects ); m_playerPuppet.AddLinkedStatusEffect( m_npcPuppet.GetEntityID(), m_playerPuppet.GetEntityID(), actionEffects ); SaveLocksManager.RequestSaveLockRemove( m_playerPuppet.GetGame(), 'PlayerBeingHacked' ); StatusEffectHelper.RemoveStatusEffect( m_playerPuppet, T"AIQuickHackStatusEffect.BeingHacked" ); if( m_ssAction ) { m_playerPuppet.RemoveLinkedStatusEffects( true ); if( !( TargetTrackingExtension.Get( ( ( ScriptedPuppet )( GameInstance.FindEntityByID( m_playerPuppet.GetGame(), m_npcSquad[ 0 ] ) ) ), targetTracker ) ) ) { if( !( TargetTrackingExtension.Get( m_npcPuppet, targetTracker ) ) ) { return false; } } TryStartCombat( m_playerPuppet, m_npcPuppet, targetTracker ); for( i = 0; i < m_npcSquad.Size(); i += 1 ) { TryStartCombat( m_playerPuppet, ( ( ScriptedPuppet )( GameInstance.FindEntityByID( m_playerPuppet.GetGame(), m_npcSquad[ i ] ) ) ), targetTracker ); } } } private function IsSquadAlive() : Bool { var squadmates : array< weak< Entity > >; var i : Int32; var squadmate : weak< ScriptedPuppet >; if( !( m_squadScriptInterface ) ) { return false; } squadmates = m_squadScriptInterface.ListMembersWeak(); for( i = 0; i < squadmates.Size(); i += 1 ) { squadmate = ( ( ScriptedPuppet )( squadmates[ i ] ) ); if( ScriptedPuppet.IsActive( squadmate ) ) { return true; } } return false; } private function StopHackBasedOnTier( currentTier : Int32 ) : Bool { var allowedInTier2 : Bool; var allowedInTier3 : Bool; var allowedInTier4 : Bool; var allowedInTier5 : Bool; allowedInTier2 = StatusEffectSystem.ObjectHasStatusEffectWithTag( ( ( GameObject )( m_playerPuppet ) ), 'AllowTracingInTier2' ); allowedInTier3 = StatusEffectSystem.ObjectHasStatusEffectWithTag( ( ( GameObject )( m_playerPuppet ) ), 'AllowTracingInTier3' ); allowedInTier4 = StatusEffectSystem.ObjectHasStatusEffectWithTag( ( ( GameObject )( m_playerPuppet ) ), 'AllowTracingInTier4' ); allowedInTier5 = StatusEffectSystem.ObjectHasStatusEffectWithTag( ( ( GameObject )( m_playerPuppet ) ), 'AllowTracingInTier5' ); if( currentTier == ( ( Int32 )( gamePSMHighLevel.SceneTier2 ) ) ) { return !( allowedInTier2 ); } else if( currentTier == ( ( Int32 )( gamePSMHighLevel.SceneTier3 ) ) ) { return !( allowedInTier3 ); } else if( currentTier == ( ( Int32 )( gamePSMHighLevel.SceneTier4 ) ) ) { return !( allowedInTier4 ); } else if( currentTier == ( ( Int32 )( gamePSMHighLevel.SceneTier5 ) ) ) { return !( allowedInTier5 ); } else if( currentTier == ( ( Int32 )( gamePSMHighLevel.Swimming ) ) ) { return true; } return false; } public override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float ) { var evt : UploadProgramProgressEvent; var quickhackShieldValue : Float; var immune : Bool; var stopHack : Bool; var playerDetected : Bool; var playerIsInCombat : Bool; var hackingMinigameBB : IBlackboard; var psmBB : IBlackboard; var statSystem : StatsSystem; var preventionSystem : PreventionSystem; var maxRevealDistance : Float; var sceneTier : Int32; playerDetected = false; playerIsInCombat = ( ( PlayerPuppet )( m_playerPuppet ) ).IsInCombat(); statSystem = GameInstance.GetStatsSystem( m_gameInstance ); preventionSystem = ( ( PreventionSystem )( GameInstance.GetScriptableSystemsContainer( m_gameInstance ).Get( 'PreventionSystem' ) ) ); quickhackShieldValue = GameInstance.GetStatsSystem( m_playerPuppet.GetGame() ).GetStatValue( m_playerPuppet.GetEntityID(), gamedataStatType.QuickhackShield ); if( m_preventionHackLoopAction ) { if( PreventionSystemHackerLoop.ShouldForceUpdateProgressBar( m_gameInstance ) ) { newValue += PreventionSystemHackerLoop.GetProgressBarForcedValue( m_gameInstance ); if( newValue > 99.98999786 ) { newValue = 100.0; } } PreventionSystemHackerLoop.UpdateOtherProgressBarReference( m_gameInstance, NULL ); PreventionSystemHackerLoop.UpdateHackLoopProgressBarValue( m_gameInstance, newValue, this ); } else { PreventionSystemHackerLoop.UpdateOtherProgressBarReference( m_gameInstance, this ); } m_HUDData.progress = newValue / 100.0; m_hudBlackboard.SetFloat( GetAllBlackboardDefs().UI_HUDProgressBar.Progress, m_HUDData.progress ); if( ( ( !( m_ssAction ) && ( newValue > 15.0 ) ) && ( quickhackShieldValue > 0.0 ) ) && !( StatusEffectSystem.ObjectHasStatusEffect( m_playerPuppet, T"BaseStatusEffect.AntiVirusCooldown" ) ) ) { StatusEffectHelper.ApplyStatusEffect( ( ( GameObject )( m_playerPuppet ) ), T"BaseStatusEffect.AntiVirusCooldown" ); immune = true; } if( m_useInterruptionPrereqs ) { stopHack = immune || m_action.CanInterrupt( m_npcPuppet ); } else { if( m_ssAction ) { hackingMinigameBB = GameInstance.GetBlackboardSystem( m_playerPuppet.GetGame() ).Get( GetAllBlackboardDefs().HackingMinigame ); psmBB = ( ( PlayerPuppet )( m_playerPuppet ) ).GetPlayerStateMachineBlackboard(); maxRevealDistance = statSystem.GetStatValue( m_playerPuppet.GetEntityID(), gamedataStatType.RevealPositionMaxDistance ); sceneTier = psmBB.GetInt( GetAllBlackboardDefs().PlayerStateMachine.HighLevel ); if( ( ( ( ( ( !( ScriptedPuppet.IsActive( m_playerPuppet ) ) || playerIsInCombat ) || ( Vector4.Distance( m_playerPuppet.GetWorldPosition(), hackingMinigameBB.GetVector4( GetAllBlackboardDefs().HackingMinigame.LastPlayerHackPosition ) ) > maxRevealDistance ) ) || StopHackBasedOnTier( sceneTier ) ) || ( !( ScriptedPuppet.IsActive( m_npcPuppet ) ) && !( IsSquadAlive() ) ) ) || ( m_shouldStopRevealOnPreventionDeescalation && !( preventionSystem.IsChasingPlayer() ) ) ) || GameInstance.GetStatusEffectSystem( m_playerPuppet.GetGame() ).HasStatusEffect( m_playerPuppet.GetEntityID(), T"BaseStatusEffect.RevealInterrupted" ) ) { stopHack = true; playerDetected = playerIsInCombat; } } else if( ( ( ( immune || !( ScriptedPuppet.IsActive( m_npcPuppet ) ) ) || !( ScriptedPuppet.IsActive( m_playerPuppet ) ) ) || ( ( m_action.GetObjectActionID() != T"AIQuickHack.HackReveal" ) && ( ( StatusEffectSystem.ObjectHasStatusEffect( m_npcPuppet, T"AIQuickHackStatusEffect.HackingInterrupted" ) || StatusEffectSystem.ObjectHasStatusEffect( m_npcPuppet, T"AIQuickHackStatusEffect.HackRevealInterrupted" ) ) || StatusEffectSystem.ObjectHasStatusEffectWithTag( m_npcPuppet, 'CyberwareMalfunction' ) ) ) ) || ( ( m_action.GetObjectActionID() == T"AIQuickHack.HackReveal" ) && playerIsInCombat ) ) { stopHack = true; } } if( stopHack ) { PreventionSystemHackerLoop.UpdateOtherProgressBarReference( m_gameInstance, NULL ); if( m_preventionHackLoopAction && ( newValue > 99.98999786 ) ) { return; } StatusEffectHelper.RemoveStatusEffect( m_playerPuppet, T"BaseStatusEffect.RevealInterrupted" ); StatusEffectHelper.RemoveStatusEffect( m_playerPuppet, T"BaseStatusEffect.ForcedQHUploadAwarenessBumps" ); ( ( PlayerPuppet )( m_playerPuppet ) ).SetIsBeingRevealed( false ); immune = false; RemoveLink( m_npcPuppet ); RemoveLinkedStatusEffects( m_npcPuppet, m_ssAction ); SaveLocksManager.RequestSaveLockRemove( m_playerPuppet.GetGame(), 'PlayerBeingHacked' ); m_HUDData.failedText = ( ( playerDetected || ( ( m_action.GetObjectActionID() == T"AIQuickHack.HackReveal" ) && playerIsInCombat ) ) ? ( "LocKey#92985" ) : ( "LocKey#15353" ) ); m_HUDData.active = false; m_hudBlackboard.SetString( GetAllBlackboardDefs().UI_HUDProgressBar.FailedText, m_HUDData.failedText ); m_hudBlackboard.SetBool( GetAllBlackboardDefs().UI_HUDProgressBar.Active, m_HUDData.active ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestRemovingStatPool( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload ); GameInstance.GetStatPoolsSystem( m_gameInstance ).RequestUnregisteringListener( m_action.GetRequesterID(), gamedataStatPoolType.QuickHackUpload, this ); evt = new UploadProgramProgressEvent; evt.state = EUploadProgramState.COMPLETED; GameInstance.GetPersistencySystem( m_gameInstance ).QueueEntityEvent( m_action.GetRequesterID(), evt ); } } } struct PlayerQuickhackData { var itemID : ItemID; var actionRecord : weak< ObjectAction_Record >; var quality : Int32; } import enum gameEPowerDifferential { IMPOSSIBLE, HARD, NORMAL, EASY, TRASH, } operator>( q1 : gamedataQuality, q2 : gamedataQuality ) : Bool { var result : Bool; if( ( ( q1 == gamedataQuality.Invalid || q1 == gamedataQuality.Count ) || q2 == gamedataQuality.Invalid ) || q2 == gamedataQuality.Count ) { return false; } switch( q1 ) { case gamedataQuality.Common: return false; case gamedataQuality.Uncommon: result = ( ( q2 == gamedataQuality.Common ) ? ( true ) : ( false ) ); break; case gamedataQuality.Rare: result = ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) ? ( true ) : ( false ) ); break; case gamedataQuality.Epic: result = ( ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) || q2 == gamedataQuality.Rare ) ? ( true ) : ( false ) ); break; case gamedataQuality.Legendary: result = ( ( ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) || q2 == gamedataQuality.Rare ) || q2 == gamedataQuality.Epic ) ? ( true ) : ( false ) ); break; default: return false; } return result; } operator>=( q1 : gamedataQuality, q2 : gamedataQuality ) : Bool { var result : Bool; if( ( ( q1 == gamedataQuality.Invalid || q1 == gamedataQuality.Count ) || q2 == gamedataQuality.Invalid ) || q2 == gamedataQuality.Count ) { return false; } switch( q1 ) { case gamedataQuality.Common: result = ( ( q2 == gamedataQuality.Common ) ? ( true ) : ( false ) ); break; case gamedataQuality.Uncommon: result = ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) ? ( true ) : ( false ) ); break; case gamedataQuality.Rare: result = ( ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) || q2 == gamedataQuality.Rare ) ? ( true ) : ( false ) ); break; case gamedataQuality.Epic: result = ( ( ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) || q2 == gamedataQuality.Rare ) || q2 == gamedataQuality.Epic ) ? ( true ) : ( false ) ); break; case gamedataQuality.Legendary: result = ( ( ( ( ( q2 == gamedataQuality.Common || q2 == gamedataQuality.Uncommon ) || q2 == gamedataQuality.Rare ) || q2 == gamedataQuality.Epic ) || q2 == gamedataQuality.Legendary ) ? ( true ) : ( false ) ); break; default: return false; } return result; } operator<( q1 : gamedataQuality, q2 : gamedataQuality ) : Bool { var result : Bool; if( ( ( q1 == gamedataQuality.Invalid || q1 == gamedataQuality.Count ) || q2 == gamedataQuality.Invalid ) || q2 == gamedataQuality.Count ) { return false; } switch( q2 ) { case gamedataQuality.Common: return false; case gamedataQuality.Uncommon: result = ( ( q1 == gamedataQuality.Common ) ? ( true ) : ( false ) ); break; case gamedataQuality.Rare: result = ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) ? ( true ) : ( false ) ); break; case gamedataQuality.Epic: result = ( ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) || q1 == gamedataQuality.Rare ) ? ( true ) : ( false ) ); break; case gamedataQuality.Legendary: result = ( ( ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) || q1 == gamedataQuality.Rare ) || q1 == gamedataQuality.Epic ) ? ( true ) : ( false ) ); break; default: return false; } return result; } operator<=( q1 : gamedataQuality, q2 : gamedataQuality ) : Bool { var result : Bool; if( ( ( q1 == gamedataQuality.Invalid || q1 == gamedataQuality.Count ) || q2 == gamedataQuality.Invalid ) || q2 == gamedataQuality.Count ) { return false; } switch( q2 ) { case gamedataQuality.Common: result = ( ( q1 == gamedataQuality.Common ) ? ( true ) : ( false ) ); break; case gamedataQuality.Uncommon: result = ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) ? ( true ) : ( false ) ); break; case gamedataQuality.Rare: result = ( ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) || q1 == gamedataQuality.Rare ) ? ( true ) : ( false ) ); break; case gamedataQuality.Epic: result = ( ( ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) || q1 == gamedataQuality.Rare ) || q1 == gamedataQuality.Epic ) ? ( true ) : ( false ) ); break; case gamedataQuality.Legendary: result = ( ( ( ( ( q1 == gamedataQuality.Common || q1 == gamedataQuality.Uncommon ) || q1 == gamedataQuality.Rare ) || q1 == gamedataQuality.Epic ) || q1 == gamedataQuality.Legendary ) ? ( true ) : ( false ) ); break; default: return false; } return result; }