Skip to content

Instantly share code, notes, and snippets.

@v1ld
Created October 31, 2024 19:35
Show Gist options
  • Save v1ld/25d0b252a1f42a558c88f5f4260ae991 to your computer and use it in GitHub Desktop.
Save v1ld/25d0b252a1f42a558c88f5f4260ae991 to your computer and use it in GitHub Desktop.
public final static func AwardExperienceFromDamage(hitEvent: ref<gameHitEvent>, damagePercentage: Float) -> Void {
let attackRecord: wref<Attack_Record>;
let i: Int32;
let player: wref<PlayerPuppet>;
let playerXPmultiplier: Float;
let queueExpRequest: ref<QueueCombatExperience>;
let queueExpRequests: array<ref<QueueCombatExperience>>;
let targetPowerLevel: Float;
let temp: Float;
let weaponRecord: wref<Item_Record>;
let attackData: ref<AttackData> = hitEvent.attackData;
let curveSetName: CName = n"activity_to_proficiency_xp";
let additionalProf: gamedataProficiencyType = gamedataProficiencyType.Invalid;
let inst: GameInstance = hitEvent.target.GetGame();
let playerDevSystem: ref<PlayerDevelopmentSystem> = GameInstance.GetScriptableSystemsContainer(inst).Get(n"PlayerDevelopmentSystem") as PlayerDevelopmentSystem;
let expAwarded: Bool = true;
let targetPuppet: wref<ScriptedPuppet> = hitEvent.target as ScriptedPuppet;
if !IsDefined(targetPuppet) || !targetPuppet.IsActive() || !targetPuppet.AwardsExperience() || !attackData.GetInstigator().IsPlayer() || hitEvent.target.IsPlayer() {
return;
};
targetPowerLevel = GameInstance.GetStatsSystem(inst).GetStatValue(Cast<StatsObjectID>(targetPuppet.GetEntityID()), gamedataStatType.PowerLevel);
playerXPmultiplier = GameInstance.GetStatsSystem(inst).GetStatValue(Cast<StatsObjectID>(GetPlayer(inst).GetEntityID()), gamedataStatType.XPbonusMultiplier);
queueExpRequest = new QueueCombatExperience();
weaponRecord = TweakDBInterface.GetItemRecord(ItemID.GetTDBID(attackData.GetWeapon().GetItemID()));
switch weaponRecord.ItemType().Type() {
case gamedataItemType.Cyb_StrongArms:
case gamedataItemType.Wea_Fists:
case gamedataItemType.Wea_Melee:
case gamedataItemType.Wea_OneHandedClub:
case gamedataItemType.Wea_Hammer:
case gamedataItemType.Wea_TwoHandedClub:
queueExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
break;
case gamedataItemType.Wea_LightMachineGun:
case gamedataItemType.Wea_HeavyMachineGun:
case gamedataItemType.Wea_ShotgunDual:
case gamedataItemType.Wea_Shotgun:
temp = weaponRecord.TagsContains(n"PowerWeapon") ? 1.00 : 0.50;
queueExpRequest.m_experienceType = gamedataProficiencyType.StrengthSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp") * temp;
break;
case gamedataItemType.Wea_SubmachineGun:
case gamedataItemType.Wea_AssaultRifle:
case gamedataItemType.Wea_Rifle:
temp = weaponRecord.TagsContains(n"PowerWeapon") ? 1.00 : 0.50;
queueExpRequest.m_experienceType = gamedataProficiencyType.ReflexesSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp") * temp;
break;
case gamedataItemType.Cyb_MantisBlades:
case gamedataItemType.Wea_Machete:
case gamedataItemType.Wea_Chainsword:
case gamedataItemType.Wea_ShortBlade:
case gamedataItemType.Wea_LongBlade:
case gamedataItemType.Wea_Sword:
case gamedataItemType.Wea_Katana:
queueExpRequest.m_experienceType = gamedataProficiencyType.ReflexesSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
break;
case gamedataItemType.Cyb_NanoWires:
queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
break;
case gamedataItemType.Wea_PrecisionRifle:
case gamedataItemType.Wea_SniperRifle:
case gamedataItemType.Wea_Revolver:
case gamedataItemType.Wea_Handgun:
temp = weaponRecord.TagsContains(n"PowerWeapon") ? 1.00 : 0.50;
queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp") * temp;
break;
case gamedataItemType.Wea_Axe:
case gamedataItemType.Wea_Knife:
queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
break;
default:
expAwarded = false;
};
if attackData.HasFlag(hitFlag.WeakspotHit) || attackData.HasFlag(hitFlag.Headshot) || attackData.HasFlag(hitFlag.FinisherTriggered) {
queueExpRequest.m_amount *= 1.10;
};
if attackData.HasFlag(hitFlag.PerfectlyCharged) {
queueExpRequest.m_amount *= 1.10;
};
if attackData.HasFlag(hitFlag.BodyPerksMeleeAttack) {
queueExpRequest.m_amount *= 1.10;
};
if expAwarded {
if StatusEffectSystem.ObjectHasStatusEffectWithTag(attackData.GetInstigator(), n"TrainingGuns") && attackData.GetWeapon().IsRanged() {
queueExpRequest.m_amount *= 2.00;
};
if StatusEffectSystem.ObjectHasStatusEffectWithTag(attackData.GetInstigator(), n"TrainingMelee") && attackData.GetWeapon().IsMelee() {
queueExpRequest.m_amount *= 2.00;
};
ArrayPush(queueExpRequests, queueExpRequest);
if weaponRecord.TagsContains(n"SmartWeapon") {
additionalProf = gamedataProficiencyType.IntelligenceSkill;
} else {
if weaponRecord.TagsContains(n"TechWeapon") {
additionalProf = gamedataProficiencyType.TechnicalAbilitySkill;
};
};
if NotEquals(additionalProf, gamedataProficiencyType.Invalid) {
temp = queueExpRequest.m_amount;
queueExpRequest = new QueueCombatExperience();
queueExpRequest.m_experienceType = additionalProf;
queueExpRequest.m_amount = temp;
ArrayPush(queueExpRequests, queueExpRequest);
};
};
if Equals(attackData.GetAttackType(), gamedataAttackType.Hack) {
queueExpRequest = new QueueCombatExperience();
queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
ArrayPush(queueExpRequests, queueExpRequest);
};
attackRecord = attackData.GetAttackDefinition().GetRecord() as Attack_GameEffect_Record;
if IsDefined(attackData.GetSource() as BaseGrenade) || IsDefined(attackData.GetSource() as ProjectileLauncherRound) || attackRecord.HitFlagsContains("Grenade") {
queueExpRequest = new QueueCombatExperience();
queueExpRequest.m_experienceType = gamedataProficiencyType.TechnicalAbilitySkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp");
ArrayPush(queueExpRequests, queueExpRequest);
};
if hitEvent.attackData.HasFlag(hitFlag.StealthHit) {
queueExpRequest = new QueueCombatExperience();
queueExpRequest.m_experienceType = gamedataProficiencyType.CoolSkill;
queueExpRequest.m_amount = GameInstance.GetStatsDataSystem(inst).GetValueFromCurve(curveSetName, targetPowerLevel, n"damage_to_skill_xp") * 0.70;
ArrayPush(queueExpRequests, queueExpRequest);
};
player = GetPlayer(inst);
i = 0;
while i < ArraySize(queueExpRequests) {
queueExpRequest = queueExpRequests[i];
queueExpRequest.owner = player;
queueExpRequest.m_amount *= RPGManager.GetRarityMultiplier(hitEvent.target as NPCPuppet, n"power_level_to_dmg_xp_mult");
queueExpRequest.m_amount *= damagePercentage;
queueExpRequest.m_amount *= playerXPmultiplier;
queueExpRequest.m_entity = targetPuppet.GetEntityID();
playerDevSystem.QueueRequest(queueExpRequest);
i += 1;
};
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(), n"CamoActiveOnPlayer") {
queueExpRequest = new QueueCombatExperience();
queueExpRequest.owner = player;
queueExpRequest.m_experienceType = gamedataProficiencyType.TechnicalAbilitySkill;
queueExpRequest.m_amount = 20.00 * playerXPmultiplier;
queueExpRequest.m_entity = targetPuppet.GetEntityID();
playerDevSystem.QueueRequest(queueExpRequest);
};
}
public final static func AwardExperienceFromDeflect(hitEvent: ref<gameHitEvent>) -> Void {
let blockingItem: wref<WeaponObject>;
let damage: Float;
let gameInstance: GameInstance;
let health: Float;
let healthPercent: Float;
let parryEffect: wref<StatusEffect>;
let playerDevSystem: ref<PlayerDevelopmentSystem>;
let playerXPmultiplier: Float;
let queueExpRequest: ref<QueueCombatExperience>;
let statPoolsSystem: ref<StatPoolsSystem>;
let player: wref<PlayerPuppet> = hitEvent.target as PlayerPuppet;
if !IsDefined(player) {
return;
};
gameInstance = player.GetGame();
blockingItem = GameInstance.GetTransactionSystem(gameInstance).GetItemInSlot(player, t"AttachmentSlots.WeaponRight") as WeaponObject;
if !IsDefined(blockingItem) {
return;
};
statPoolsSystem = GameInstance.GetStatPoolsSystem(gameInstance);
damage = hitEvent.attackComputed.GetTotalAttackValue(gamedataStatPoolType.Health);
healthPercent = statPoolsSystem.GetStatPoolValue(Cast<StatsObjectID>(player.GetEntityID()), gamedataStatPoolType.Health);
health = statPoolsSystem.ToPoints(Cast<StatsObjectID>(player.GetEntityID()), gamedataStatPoolType.Health, healthPercent);
damage = (damage * healthPercent) / health;
parryEffect = StatusEffectHelper.GetStatusEffectByID(player, t"BaseStatusEffect.ParryExpHarvested");
if damage <= 0.00 || IsDefined(parryEffect) && parryEffect.GetMaxStacks() <= parryEffect.GetStackCount() {
return;
};
playerDevSystem = GameInstance.GetScriptableSystemsContainer(gameInstance).Get(n"PlayerDevelopmentSystem") as PlayerDevelopmentSystem;
playerXPmultiplier = GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(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 final static func AwardExperienceFromLocomotion(player: wref<PlayerPuppet>, amount: Float) -> Void {
let cachedExp: Int32;
let gameInstance: GameInstance;
let playerDevSystem: ref<PlayerDevelopmentSystem>;
let playerXPmultiplier: Float;
let queueExpRequest: ref<AddExperience>;
let statMod: ref<gameConstantStatModifierData>;
let statsSystem: ref<StatsSystem>;
let statusEffect: ref<StatusEffect>;
let stat: gamedataStatType = gamedataStatType.LocomotionExperienceReward;
if !IsDefined(player) || amount <= 0.00 {
return;
};
statusEffect = StatusEffectHelper.GetStatusEffectByID(player, t"BaseStatusEffect.LocomotionExpHarvested");
if IsDefined(statusEffect) && statusEffect.GetMaxStacks() <= statusEffect.GetStackCount() {
return;
};
gameInstance = player.GetGame();
playerDevSystem = GameInstance.GetScriptableSystemsContainer(gameInstance).Get(n"PlayerDevelopmentSystem") as PlayerDevelopmentSystem;
statsSystem = GameInstance.GetStatsSystem(gameInstance);
playerXPmultiplier = GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(player.GetEntityID()), gamedataStatType.XPbonusMultiplier);
statMod = RPGManager.CreateStatModifier(stat, gameStatModifierType.Additive, amount * playerXPmultiplier) as gameConstantStatModifierData;
statsSystem.AddModifier(Cast<StatsObjectID>(player.GetEntityID()), statMod);
cachedExp = Cast<Int32>(statsSystem.GetStatValue(Cast<StatsObjectID>(player.GetEntityID()), stat));
if cachedExp >= 100 {
queueExpRequest = new AddExperience();
queueExpRequest.Set(player, cachedExp, gamedataProficiencyType.ReflexesSkill, false);
playerDevSystem.QueueRequest(queueExpRequest);
statMod = RPGManager.CreateStatModifier(stat, gameStatModifierType.Additive, Cast<Float>(cachedExp) * -1.00) as gameConstantStatModifierData;
statsSystem.AddModifier(Cast<StatsObjectID>(player.GetEntityID()), statMod);
};
StatusEffectHelper.ApplyStatusEffect(player, t"BaseStatusEffect.LocomotionExpHarvested", player.GetEntityID());
}
public final static func AwardExperienceFromResourceSpent(player: wref<PlayerPuppet>, value: Float, type: gamedataStatPoolType, opt hitEvent: ref<gameHitEvent>) -> Void {
let gameInstance: GameInstance;
let playerDevSystem: ref<PlayerDevelopmentSystem>;
let playerXPmultiplier: Float;
let queueCombatExpRequest: ref<QueueCombatExperience>;
if !IsDefined(player) {
return;
};
gameInstance = player.GetGame();
playerDevSystem = GameInstance.GetScriptableSystemsContainer(gameInstance).Get(n"PlayerDevelopmentSystem") as PlayerDevelopmentSystem;
playerXPmultiplier = GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(player.GetEntityID()), gamedataStatType.XPbonusMultiplier);
if Equals(type, gamedataStatPoolType.Overshield) && IsDefined(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 final static func AwardExperienceFromQuickhack(player: wref<PlayerPuppet>, cost: Float, target: EntityID, category: gamedataHackCategory) -> Void {
let gameInstance: GameInstance;
let playerDevSystem: ref<PlayerDevelopmentSystem>;
let playerXPmultiplier: Float;
let queueExpRequest: ref<AddExperience>;
let statusEffect: wref<StatusEffect>;
let targetObj: wref<GameObject>;
let targetPowerLevel: Float;
let multiplier: Float = 1.00;
if !IsDefined(player) || !EntityID.IsDefined(target) || Equals(category, gamedataHackCategory.NotAHack) {
return;
};
targetObj = GameInstance.FindEntityByID(gameInstance, target) as GameObject;
statusEffect = StatusEffectHelper.GetStatusEffectByID(targetObj, t"BaseStatusEffect.QuickhackExpHarvested");
if IsDefined(statusEffect) && statusEffect.GetMaxStacks() <= statusEffect.GetStackCount() {
return;
};
gameInstance = player.GetGame();
playerDevSystem = GameInstance.GetScriptableSystemsContainer(gameInstance).Get(n"PlayerDevelopmentSystem") as PlayerDevelopmentSystem;
playerXPmultiplier = GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(player.GetEntityID()), gamedataStatType.XPbonusMultiplier);
targetPowerLevel = GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(target), gamedataStatType.PowerLevel);
if GameInstance.GetStatsSystem(gameInstance).GetStatValue(Cast<StatsObjectID>(target), gamedataStatType.WasQuickHacked) < 1.00 {
multiplier = 20.00;
};
if Equals(category, gamedataHackCategory.DeviceHack) {
multiplier *= 0.30;
};
queueExpRequest = new AddExperience();
queueExpRequest.owner = player;
queueExpRequest.m_experienceType = gamedataProficiencyType.IntelligenceSkill;
queueExpRequest.m_amount = Cast<Int32>((cost * 0.70 + targetPowerLevel * 0.20) * playerXPmultiplier * multiplier * 0.50);
playerDevSystem.QueueRequest(queueExpRequest);
StatusEffectHelper.ApplyStatusEffect(targetObj, t"BaseStatusEffect.QuickhackExpHarvested", player.GetEntityID());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment