2023-02-06

Research for BlackLace gameplay mechanics

BlackLace

Cyberpunk RED

Cost per Dose: 50eb (Costly)

Primary Effect

• Lasts 24 Hours. • User takes 2d6 Humanity Loss upon taking a dose, which is returned if the user isn't affected by Black Lace's Secondary Effect. • For the duration of the Primary Effect, the user ignores the effects of the Seriously Wounded Wound State.

Black Lace's Secondary Effect.

• Humanity Loss from Primary Effect isn't returned. • If the user wasn't already addicted to Black Lace, they are now. While addicted, unless the user is currently experiencing the Primary Effect of Black Lace, their REF is lowered by 2 points.

Drugs core rules

When you are dosed with one of these drugs, you are automatically affected by the drug's Primary Effect. When the Primary Effect of the drug wears off at the end of its duration, you roll WILL + Resist Torture/ Drugs + 1d10 against the DV of the drug's Secondary Effect, which are permanent and habit forming until you receive therapy for addiction. Taking multiple doses of a drug extends the primary effect of a drug by its full duration.

Cyberpunk Fandom

Using Black Lace will increase Armor by 10 for 30 seconds.

Black Lace is a drug that increases adrenaline and endorphins levels up to the point that one is almost incapable of feeling pain. The trip is so intense that it verges on cyberpsychosis. Corporations handed it out to their forces during the Corporate Wars. Cyberpsychos are heavy consumers of the drug. Vaporizing the drug instead of swallowing it lessens the aftereffects, without compromising the trip.

Alias: s-keef Rarity: Rare

Internet browsing

Adrenaline

Adrenaline, also known as epinephrine, is a hormone and medication which is involved in regulating visceral functions (e.g., respiration). It appears as a white microcrystalline granule. Adrenaline is normally produced by the adrenal glands and by a small number of neurons in the medulla oblongata.

It plays an essential role in the fight-or-flight response by increasing blood flow to muscles, heart output by acting on the SA node, pupil dilation response, and blood sugar level. It does this by binding to alpha and beta receptors. It is found in many animals, including humans, and some single-celled organisms. It has also been isolated from the plant Scoparia dulcis found in Northern Vietnam.

Endorphins

Endorphins (contracted from endogenous morphine) are chemical signals in the brain that block the perception of pain and increase feelings of wellbeing. They are produced and stored in an area of the brain known as the pituitary gland.

Endorphins are released when your body feels pain or stress. Your body releases endorphins to help you survive. When you feel pain, nerves in your body send pain signals to your brain. Your brain releases endorphins to block the nerve cells that receive the pain signals.

This essentially turns off your pain. It helps you to continue functioning, even in painful or stressful situations. Because you naturally seek to avoid pain, you’re more likely to do something if it makes you feel good.

Lack of endorphin

People with a lack of endorphins may show signs of depression. This is because of a lack of dopamine. Other effects of endorphin deficiency can include: Fibromyalgia: a condition that causes chronic pain throughout your body.

Fibromyalgia

Fibromyalgia is a disorder characterized by widespread musculoskeletal pain accompanied by fatigue, sleep, memory and mood issues. Researchers believe that fibromyalgia amplifies painful sensations by affecting the way your brain and spinal cord process painful and nonpainful signals.

Research : handle potential UI inconsistencies

Fact is, player can keep interacting with everything around, pause game, or even browse the various menus (inventory, character, etc). So how to track this ? It's probably related in one way or another to the game controllers (e.g. TimeskipGameController). Here's a quick and probably incomplete list:

  • MainMenuGameController
  • MiniGameControllerAdvanced / MiniGamePlayerController
  • inkHUDGameController -> ShowRequest / HideRequest
  • attention: e.g. TimeskipGameController just extends inkGameController !
  • NetworkInkGameController
  • BrowserGameController
  • ControlledDevicesInkGameController ?
  • SceneScreenGameController ?
  • HoldIndicatorGameController ?
  • TutorialMainController
  • FastTravelGameController
  • BaseHubMenuController ?
  • PauseMenuBackgroundGameController / PauseMenuGameController
  • CodexPopupGameController
  • gameuiPhotoModeMenuController
  • BoothModeGameController
  • TarotPreviewGameController
  • BaseModalListPopupGameController
  • VendorSellJunkPopup
  • CpoHudRootGameController seems unrelated as it's talking about multi and assets cannot be found in WK

    multi like 'multiplayer' ?

On opening some UI, the biomonitor animation should just be dismissed (e.g. whenever time passes, like when skipping time / going to sleep, if confirmed).

On opening other UI, the biomonitor animation should just pause (e.g. whenever in inventory or any of the other siblings menus), and resume when back in-game.

Research : create a custom interaction with player

Like the one where you have to quick take a decision (the UI with the decreasing bar and the button to take action). Which classes could provide this feature ?

  • gameinteractionsReactionState
  • gameinteractionsChoiceType
  • EFocusForcedHighlightType
  • gamedataMappinVariant
  • EQuestVehicleDoorState.DisableAllInteractions
  • EDrillMachineRewireState.OutsideInteractionRange
  • EDPadSlot.InteractionWheel
  • InteractionManager
  • InteractionChoiceCaptionPart
  • InteractionChoice
  • InteractionBaseEvent
  • InteractionComponent.SetSingleChoice
  • InteractionActivationEvent
  • InteractionChoiceEvent
  • InteractionScriptedCondition (e.g. DeviceRemoteInteractionCondition)
  Redscript
this.m_DPadWheelInterationStartedBBID = this.m_UiQuickItemsBlackboard.RegisterDelayedListenerVariant(this.m_UiQuickSlotDef.WheelInteractionStarted, this, n"OnWheelInteractionStarted");
this.m_DPadWheelInterationEndedBBID = this.m_UiQuickItemsBlackboard.RegisterDelayedListenerVariant(this.m_UiQuickSlotDef.WheelInteractionEnded, this, n"OnWheelInteractionEnded");
  Redscript
this.m_interactionBlackboardId = this.m_bbUIData.RegisterListenerVariant(GetAllBlackboardDefs().UIGameData.InteractionData, this, n"OnInteractionStateChange");
protected cb func OnInteractionStateChange(value: Variant) -> Bool {
  let interactionData: bbUIInteractionData = FromVariant<bbUIInteractionData>(value);
  this.m_interactionDeviceState = interactionData.terminalInteractionActive;
  this.UpdateIsInteractingWithDevice();
}
  Redscript
this.m_bbDefinition = GetAllBlackboardDefs().UIInteractions;
this.m_dataListenerId = this.m_blackboard.RegisterDelayedListenerVariant(this.m_bbDefinition.LootData, this, n"OnUpdateData");
// https://jac3km4.github.io/cyberdoc/#17638 => UIInteractionsDef
// InteractionChoiceHub: BlackboardID_Variant
// DialogChoiceHubs: BlackboardID_Variant
// LootData: BlackboardID_Variant
// ContactsData: BlackboardID_Variant
// ActiveChoiceHubID: BlackboardID_Int
// SelectedIndex: BlackboardID_Int
// ActiveInteractions: BlackboardID_Variant
// InteractionSkillCheckHub: BlackboardID_Variant
// NameplateOwnerID: BlackboardID_EntityID
// VisualizersInfo: BlackboardID_Variant
// ShouldHideClampedMappins: BlackboardID_Bool
// LastAttemptedChoice: BlackboardID_Variant
// LookAtTargetVisualizerID: BlackboardID_Int
// HasScrollableInteraction: BlackboardID_Bool

Actually there's a lot of things to look at in blackboardDefinitions.swift.

  • PlayerStateMachineDef
    • IsInteractingWithDevice
    • IsInteractingViaPersonalLink
    • IsUploadingQuickHack
    • DisplayDeathMenu
    • IsInWorkspot
    • IsInLoreAnimationScene
  • UI_SystemDef
    • IsInMenu
  • UIGameDataDef
    • Popup_IsModal
    • Popup_IsShown
    • IsBriefingActive
  • UIInteractionsDef
    • ActiveInteractions
  • UI_ActiveVehicleDataDef
    • IsPlayerMounted
  • VehicleDef
    • IsUIActive
  • BraindanceBlackboardDef
    • IsActive
  • UI_PlayerBioMonitorDef
    • AdrenalineBar
  • FastTRavelSystemDef
    • FastTravelStarted
  • DeviceBaseBlackboardDef
    • UI_InteractivityBlocked
  • MenuEventBlackboardDef
    • MenuEventToTrigger
  • UI_ComDeviceDef
    • isDisplayingMessage
  • HUDManagerDef
    • ShowHudHintMessege
  • UI_HUDProgressBarDef
    • Active
  • UI_QuickSlotsDataDef
    • WheelInteractionStarted
    • WheelInteractionEnded
    • UIRadialContextRequest
    • quickhackPanelOpen
  • PhotoModeDef
    • Active

Wow, that's a lot to investigate ! And there's also gamedataStatType that I would like to look further out.

Here are also a few samples from the sources:

from PlayerPuppet

  Redscript
protected cb func OnDeath(evt: ref<gameDeathEvent>) -> Bool {
  this.ForceCloseRadialWheel();
  StatusEffectHelper.ApplyStatusEffect(this, t"GameplayRestriction.BlockAllHubMenu");
  super.OnDeath(evt);
  GameInstance.GetTelemetrySystem(this.GetGame()).LogPlayerDeathEvent(evt);
}

from DefaultTransition

  Redscript
protected final const func IsPlayerInAnyMenu(const scriptInterface: ref<StateGameScriptInterface>) -> Bool {
  let blackboard: ref<IBlackboard> = scriptInterface.GetBlackboardSystem().Get(GetAllBlackboardDefs().UI_System);
  let uiSystemBB: ref<UI_SystemDef> = GetAllBlackboardDefs().UI_System;
  return blackboard.GetBool(uiSystemBB.IsInMenu);
}
protected final const func IsQuickHackPanelOpened(const scriptInterface: ref<StateGameScriptInterface>) -> Bool {
  let bb: ref<IBlackboard> = scriptInterface.GetBlackboardSystem().Get(GetAllBlackboardDefs().UI_QuickSlotsData);
  return bb.GetBool(GetAllBlackboardDefs().UI_QuickSlotsData.quickhackPanelOpen);
}

protected final const func IsRadialWheelOpen(const scriptInterface: ref<StateGameScriptInterface>) -> Bool {
  let bb: ref<IBlackboard> = scriptInterface.GetBlackboardSystem().Get(GetAllBlackboardDefs().UI_QuickSlotsData);
  return bb.GetBool(GetAllBlackboardDefs().UI_QuickSlotsData.UIRadialContextRequest);
}

MovePoliciesComponent

  Redscript
public final native func IsInIdle() -> Bool;

HUDManager

  Redscript
private final func RegisterHackingMinigameCallback() -> Void {
  let blackboard: ref<IBlackboard> = GameInstance.GetBlackboardSystem(this.GetGameInstance()).Get(GetAllBlackboardDefs().NetworkBlackboard);
  if IsDefined(blackboard) && !IsDefined(this.m_hackingMinigameCallbackID) {
    this.m_hackingMinigameCallbackID = GameInstance.GetBlackboardSystem(this.GetGameInstance()).Get(GetAllBlackboardDefs().NetworkBlackboard).RegisterListenerString(GetAllBlackboardDefs().NetworkBlackboard.NetworkName, this, n"OnBreachingNetwork");
  };
}

AttackData

  Redscript
public final static func IsPlayerInCombat(attackData: ref<AttackData>) -> Bool {
  let psmBB: ref<IBlackboard> = GameInstance.GetBlackboardSystem(GetGameInstance()).GetLocalInstanced(attackData.GetInstigator().GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine);
  let combatState: Int32 = psmBB.GetInt(GetAllBlackboardDefs().PlayerStateMachine.Combat);
  return combatState == EnumInt(gamePSMCombat.InCombat);
}

ArcadeMachineController

  Redscript
protected final const func IsPlayerInteractingWithDevice() -> Bool {
  let playerStateMachineBlackboard: ref<IBlackboard> = GameInstance.GetBlackboardSystem(this.GetGameInstance()).GetLocalInstanced(this.GetPlayerEntityID(), GetAllBlackboardDefs().PlayerStateMachine);
  return playerStateMachineBlackboard.GetBool(GetAllBlackboardDefs().PlayerStateMachine.IsInteractingWithDevice);
}