Skip to content

Commit

Permalink
Merge pull request #123 from cyb3rpsych0s1s/fix/neuroblockers
Browse files Browse the repository at this point in the history
NeuroBlockers increase faster when using neurostimulants
  • Loading branch information
Roms1383 authored Apr 26, 2024
2 parents f89c8c1 + 854bc9f commit 9171883
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 22 deletions.
6 changes: 5 additions & 1 deletion scripts/Addicted/Definitions.reds
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ public class Consumptions {
public func Items() -> array<ItemID> {
let items: array<ItemID> = [];
for key in this.keys {
ArrayPush(items, ItemID.FromTDBID(key));
if Generic.IsContraindicated(key) {
ArrayPush(items, ItemID.CreateQuery(key));
} else {
ArrayPush(items, ItemID.FromTDBID(key));
}
}
return items;
}
Expand Down
16 changes: 16 additions & 0 deletions scripts/Addicted/Effectors.reds
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Addicted

import Addicted.System.AddictedSystem
import Addicted.Utils.F

public class IncreaseNeuroBlockerEffector extends Effector {
protected func ActionOn(owner: ref<GameObject>) -> Void {
let system = AddictedSystem.GetInstance(owner.GetGame());
let id = TDBID.Create("Items.ripperdoc_med_contraindication");
// grant a unique ID to differentiate, see:
// - Generic.IsNeuroBlocker
// - Generic.IsContraindicated
// - Consumptions.Items
system.OnContraindication(ItemID.CreateQuery(id));
}
}
4 changes: 3 additions & 1 deletion scripts/Addicted/Helper.reds
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public func IsLanguageSupported(locale: CName) -> Bool {
}

public class Helper {
public static func Potency(id: ItemID, subsequentUse: Bool) -> Int32 {
public static func Potency(id: ItemID, subsequentUse: Bool, modifier: Float) -> Int32 {
let consumableName = Generic.Consumable(id);
switch(consumableName) {
Expand All @@ -28,6 +28,8 @@ public class Helper {
case Consumable.OxyBooster:
case Consumable.MemoryBooster:
return subsequentUse ? 4 : 6;
case Consumable.NeuroBlocker:
return subsequentUse ? RoundMath(1. * modifier) : RoundMath(3. * modifier);
}
return subsequentUse ? 1 : 2;
}
Expand Down
3 changes: 0 additions & 3 deletions scripts/Addicted/Prereqs.reds
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
module Addicted

public class NoCorpoDistricts extends IScriptablePrereq {
protected func Initialize(recordID: TweakDBID) -> Void {}
public const func IsFulfilled(game: GameInstance, context: ref<IScriptable>) -> Bool {
let ps: ref<PreventionSystem> = GameInstance.GetScriptableSystemsContainer(game).Get(n"PreventionSystem") as PreventionSystem;
let district = ps.GetCurrentDistrict().GetDistrictID();
Expand Down
96 changes: 81 additions & 15 deletions scripts/Addicted/System.reds
Original file line number Diff line number Diff line change
Expand Up @@ -185,31 +185,90 @@ public class AddictedSystem extends ScriptableSystem {
this.updateSymtomsID = this.delaySystem.DelayCallback(callback, 600., true);
}
public func OnConsumeItem(itemID: ItemID) -> Void {
let id = ItemID.GetTDBID(itemID);
E(s"consume item \(TDBID.ToStringDEBUG(id))");
if !this.player.PastPrologue() {
E(s"no consumption tracked during prologue");
return;
private func CalculateConsumptionModifier(identifier: TweakDBID) -> Float {
E(s"CalculateConsumptionModifier(\(TDBID.ToStringDEBUG(identifier)))");
if !Generic.IsNeuroBlocker(identifier) { return 1.0; }
let packages = GameInstance.GetGameplayLogicPackageSystem(this.player.GetGame());
let applied: array<TweakDBID>;
packages.GetAppliedPackages(this.player, applied);
let specifics: array<wref<StatModifier_Record>> = [];
let modifiers: array<wref<StatModifier_Record>>;
let package: wref<GameplayLogicPackage_Record>;
let modifier: wref<StatModifier_Record>;
let id: TweakDBID;
let i: Int32;
while i < ArraySize(applied) {
ArrayClear(modifiers);
id = applied[i];
if Equals(id, t"Packages.NeuroStimuliExDisk")
|| Equals(id, t"Packages.NeuroStimuliBioconductor")
|| Equals(id, t"Packages.NeuroStimuliCOX2") {
package = TweakDBInterface.GetGameplayLogicPackageRecord(id);
modifier = package.GetStatsItem(0);
ArrayPush(specifics, modifier);
}
i += 1;
}
let before: Threshold;
let total: Float = RPGManager.CalculateStatModifiers(specifics, this.player.GetGame(), this.player, Cast<StatsObjectID>(this.player.GetEntityID()));
if total < 1.0 {
total = 1.0;
}
E(s"total: \(total)");
return total;
}
private func ProcessConsume(itemID: ItemID) -> Consumed {
let id = ItemID.GetTDBID(itemID);
let consumed: Consumed;
let amount: Int32;
let hint: Bool;
let before: Threshold;
let after: Threshold;
let daysPast: Int32;
if Generic.IsAddictive(id) {
let addictive = Generic.IsAddictive(id);
let contraindicated = Generic.IsContraindicated(itemID);
if addictive || contraindicated {
let usedToday = this.DaysSinceLastConsumption(Generic.Consumable(id)) == 0;
let modifier: Float = this.CalculateConsumptionModifier(id);
if this.consumptions.KeyExist(itemID) {
let consumption: ref<Consumption> = this.consumptions.Get(itemID);
before = Helper.Threshold(consumption.current);
amount = Min(consumption.current + Helper.Potency(itemID, usedToday), 100);
amount = Min(consumption.current + Helper.Potency(itemID, usedToday, modifier), 100);
} else {
before = Threshold.Clean;
amount = Helper.Potency(itemID, usedToday);
amount = Helper.Potency(itemID, usedToday, modifier);
}
after = Helper.Threshold(amount);
hint = this.Consume(itemID, amount);
}
consumed.amount = amount;
consumed.hint = hint;
consumed.before = before;
consumed.after = after;
return consumed;
}
public func OnContraindication(itemID: ItemID) -> Void {
let id = ItemID.GetTDBID(itemID);
E(s"contraindicated usage \(TDBID.ToStringDEBUG(id))");
let consumed: Consumed = this.ProcessConsume(itemID);
if NotEquals(EnumInt(consumed.before), EnumInt(consumed.after)) {
this.CheckWarn();
}
}
public func OnConsumeItem(itemID: ItemID) -> Void {
let consumed: Consumed;
let id = ItemID.GetTDBID(itemID);
E(s"consume item \(TDBID.ToStringDEBUG(id))");
if !this.player.PastPrologue() {
E(s"no consumption tracked during prologue");
return;
}
if Generic.IsAddictive(id) {
consumed = this.ProcessConsume(itemID);
let consumable: Consumable = Generic.Consumable(id);
if NotEquals(EnumInt(consumable), EnumInt(Consumable.Invalid)) {
Expand All @@ -220,11 +279,11 @@ public class AddictedSystem extends ScriptableSystem {
blackboard.SetUint(GetAllBlackboardDefs().PlayerStateMachine.WithdrawalSymptoms, next, true);
} else { F(s"invalid consumable: \(TDBID.ToStringDEBUG(id))"); }
E(s"consumption hint: \(ToString(hint))");
if hint {
E(s"consumption hint: \(ToString(consumed.hint))");
if consumed.hint {
this.Hint(id);
}
if NotEquals(EnumInt(before), EnumInt(after)) {
if NotEquals(EnumInt(consumed.before), EnumInt(consumed.after)) {
if Generic.IsHealer(id) { this.UpdateHealingChargeDuration(this.player); }
this.CheckWarn();
}
Expand Down Expand Up @@ -649,4 +708,11 @@ private func OnAddictedPostAttach(system: ref<AddictedSystem>) -> Void { ModSett
@if(!ModuleExists("ModSettingsModule"))
private func OnAddictedPostDetach(_: ref<AddictedSystem>) -> Void {}
@if(ModuleExists("ModSettingsModule"))
private func OnAddictedPostDetach(system: ref<AddictedSystem>) -> Void { ModSettings.UnregisterListenerToModifications(system); }
private func OnAddictedPostDetach(system: ref<AddictedSystem>) -> Void { ModSettings.UnregisterListenerToModifications(system); }

struct Consumed {
let amount: Int32;
let hint: Bool;
let before: Threshold;
let after: Threshold;
}
6 changes: 6 additions & 0 deletions scripts/Addicted/Tweaks.reds
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,9 @@ private final func Apply() -> Void {
}
wrappedMethod();
}

@wrapMethod(RPGManager)
public final static func IncrementQuickHackBlackboard(gameInstance: GameInstance, actionID: TweakDBID) -> Void {
ModLog(n"RPGManager.IncrementQuickHackBlackboard", TDBID.ToStringDEBUG(actionID));
wrappedMethod(gameInstance, actionID);
}
14 changes: 13 additions & 1 deletion scripts/Addicted/helpers/Generic.reds
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,16 @@ public class Generic {
let suffix = StrAfterFirst(str, ".");
return StrContains(suffix, "RipperDocMedBuff") || StrContains(suffix, "ripperdoc_med");
}
}
public static func IsContraindicated(item: ItemID) -> Bool {
if !ItemID.IsQuery(item) { return false; }
let id = ItemID.GetTDBID(item);
return Generic.IsContraindicated(id);
}
public static func IsContraindicated(id: TweakDBID) -> Bool {
let str = TDBID.ToStringDEBUG(id);
let suffix = StrAfterFirst(str, ".");
return StrContains(suffix, "contraindication");
}
}
16 changes: 16 additions & 0 deletions scripts/Addicted/helpers/Items.reds
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,24 @@ import Addicted.Utils.{E,EI,F}
// items helper
public class Items {
private static func Suffix(id: TweakDBID) -> String {
let raw: String = TDBID.ToStringDEBUG(id);
let prefix: String;
let suffix: String;
StrSplitFirst(raw, ".", prefix, suffix);
return suffix;
}
private static func SuffixContains(id: TweakDBID, keyword: String) -> Bool {
let suffix: String = Items.Suffix(id);
return StrContains(suffix, keyword);
}
public static func IsDetoxifier(id: TweakDBID) -> Bool { return Equals(id, t"Items.ToxinCleanser"); }
public static func IsMetabolicEditor(id: TweakDBID) -> Bool { return Equals(id, t"Items.ReverseMetabolicEnhancer"); }
public static func IsBioconductor(id: TweakDBID) -> Bool { return StrBeginsWith(Items.Suffix(id), "AdvancedBioConductors"); }
public static func IsCOX2(id: TweakDBID) -> Bool { return StrBeginsWith(Items.Suffix(id), "IconicBioConductors"); }
public static func IsExDisk(id: TweakDBID) -> Bool { return StrBeginsWith(Items.Suffix(id), "AdvancedExDisk"); }
public static func IsCamillo(id: TweakDBID) -> Bool { return StrBeginsWith(Items.Suffix(id), "AdvancedCamilloRamManager"); }
public static func IsInstant(record: ref<TweakDBRecord>) -> Bool {
// TODO: refactor based on duration < 1
if record.IsA(n"gamedataConsumableItem_Record") {
Expand Down
143 changes: 142 additions & 1 deletion tweaks/Addicted/crossover.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# weakened neuroblockers status effect
# neuroblocker potency's modifier

BaseStats.NeuroBlockersPotencyModifier:
$type: Stat
enumName: NeuroBlockersPotencyModifier
min: 1
max: 3

# weakened neuroblocker icons

UIIcon.NotablyWeakenedNeuroblocker:
$type: UIIcon_Record
Expand All @@ -9,3 +17,136 @@ UIIcon.SeverelyWeakenedNeuroblocker:
$type: UIIcon_Record
atlasPartName: severely_weakened_inhaler_buff_icon
atlasResourcePath: addicted\gameplay\gui\widgets\healthbar\atlas_buffinfo.inkatlas

# check if any neuroblocker has been consumed

Prereqs.RipperDocMedBuff:
$type: StatusEffectPrereq_Record
prereqClassName: StatusEffectPrereq
statusEffect: BaseStatusEffect.RipperDocMedBuff

Prereqs.RipperDocMedBuffUncommon:
$type: StatusEffectPrereq_Record
prereqClassName: StatusEffectPrereq
statusEffect: BaseStatusEffect.RipperDocMedBuffUncommon

Prereqs.RipperDocMedBuffCommon:
$type: StatusEffectPrereq_Record
prereqClassName: StatusEffectPrereq
statusEffect: BaseStatusEffect.RipperDocMedBuffCommon

Prereqs.ConsumedAnyNeuroBlocker:
$type: gamedataMultiPrereq_Record
aggregationType: OR
prereqClassName: gameMultiPrereq
nestedPrereqs:
- Prereqs.RipperDocMedBuff
- Prereqs.RipperDocMedBuffUncommon
- Prereqs.RipperDocMedBuffCommon

# combine RAM replenishment prereq with neuroblocker consumption's

Prereqs.ShouldReplenishRAM:
$base: Items.MemoryReplenishmentEffector_inline0

Prereqs.StimuliRAM:
$type: gamedataMultiPrereq_Record
aggregationType: AND
prereqClassName: gameMultiPrereq
nestedPrereqs:
- Prereqs.ConsumedAnyNeuroBlocker
- Prereqs.ShouldReplenishRAM

# increase neuroblocker's jauge when using time dilation wares after consumption

Effectors.NeuroWare:
$type: Effector_Record
prereqRecord: Prereqs.ConsumedAnyNeuroBlocker
effectorClassName: Addicted.IncreaseNeuroBlockerEffector
removeAfterActionCall: true

Packages.ContraindicatedWare:
$type: GameplayLogicPackage_Record
effectors:
- Effectors.NeuroWare

BaseStatusEffect.SandevistanPlayerBuff.packages: &NeuroWare
- !append-once Packages.ContraindicatedWare
BaseStatusEffect.KerenzikovPlayerBuff.packages: *NeuroWare
BaseStatusEffect.KerenzikovsBoostSystemBuff.packages: *NeuroWare

# increase neuroblocker's jauge when RAM gets replenished after consumption

Effectors.NeuroTrigger:
$base: Effectors.NeuroWare
prereqRecord: Prereqs.StimuliRAM

Items.AdvancedCamilloRamManagerEpic_inline0.effectors: &NeuroTrigger
- !append-once Effectors.NeuroTrigger
Items.AdvancedCamilloRamManagerEpicPlus_inline1.effectors: *NeuroTrigger
Items.AdvancedCamilloRamManagerLegendary_inline1.effectors: *NeuroTrigger
Items.AdvancedCamilloRamManagerLegendaryPlus_inline1.effectors: *NeuroTrigger
Items.AdvancedCamilloRamManagerLegendaryPlusPlus_inline1.effectors: *NeuroTrigger

# using neuro-stimuli intensive wares increase its potency

Modifiers.NeuroStimuli:
$type: ConstantStatModifier_Record
modifierType: AdditiveMultiplier
statType: BaseStats.NeuroBlockersPotencyModifier
value: 0.5

Modifiers.NeuroStimuliExDisk:
$base: Modifiers.NeuroStimuli

Modifiers.NeuroStimuliBioconductor:
$base: Modifiers.NeuroStimuli

Modifiers.NeuroStimuliCOX2:
$base: Modifiers.NeuroStimuli

Packages.NeuroStimuliExDisk:
$type: GameplayLogicPackage_Record
stats:
- Modifiers.NeuroStimuliExDisk

Packages.NeuroStimuliBioconductor:
$type: GameplayLogicPackage_Record
stats:
- Modifiers.NeuroStimuliBioconductor

Packages.NeuroStimuliCOX2:
$type: GameplayLogicPackage_Record
stats:
- Modifiers.NeuroStimuliCOX2

Items.AdvancedExDiskRare.OnEquip: &NeuroStimuliExDisk
- !append-once Packages.NeuroStimuliExDisk
Items.AdvancedExDiskRarePlus.OnEquip: *NeuroStimuliExDisk
Items.AdvancedExDiskEpic.OnEquip: *NeuroStimuliExDisk
Items.AdvancedExDiskEpicPlus.OnEquip: *NeuroStimuliExDisk
Items.AdvancedExDiskLegendary.OnEquip: *NeuroStimuliExDisk
Items.AdvancedExDiskLegendaryPlus.OnEquip: *NeuroStimuliExDisk
Items.AdvancedExDiskLegendaryPlusPlus.OnEquip: *NeuroStimuliExDisk

Items.AdvancedBioConductorsCommon.OnEquip: &NeuroStimuliBioconductor
- !append-once Packages.NeuroStimuliBioconductor
Items.AdvancedBioConductorsCommonPlus.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsUncommon.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsUncommonPlus.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsRare.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsRarePlus.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsEpic.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsEpicPlus.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsLegendary.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsLegendaryPlus.OnEquip: *NeuroStimuliBioconductor
Items.AdvancedBioConductorsLegendary_PlusPlus.OnEquip: *NeuroStimuliBioconductor

Items.IconicBioConductorsRare.OnEquip: &NeuroStimuliCOX2
- !append-once Packages.NeuroStimuliCOX2
Items.IconicBioConductorsRarePlus.OnEquip: *NeuroStimuliCOX2
Items.IconicBioConductorsEpic.OnEquip: *NeuroStimuliCOX2
Items.IconicBioConductorsEpicPlus.OnEquip: *NeuroStimuliCOX2
Items.IconicBioConductorsLegendary.OnEquip: *NeuroStimuliCOX2
Items.IconicBioConductorsLegendaryPlus.OnEquip: *NeuroStimuliCOX2
Items.IconicBioConductorsLegendaryPlusPlus.OnEquip: *NeuroStimuliCOX2

0 comments on commit 9171883

Please sign in to comment.