-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 510e0ae
Showing
4 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0"?> | ||
<bindings> | ||
<!-- inputContexts --> | ||
<context name="InteractionActions" append="true"> | ||
<action name="ChoiceDisassemble_Hold" map="ChoiceDisassemble" priority="-2" /> | ||
</context> | ||
|
||
<hold action="ChoiceDisassemble_Hold" timeout="0.3" /> | ||
|
||
<acceptedEvents action="ChoiceDisassemble_Hold" > | ||
<event name="BUTTON_HOLD_COMPLETE" /> | ||
</acceptedEvents> | ||
|
||
<!-- inputUserMapping --> | ||
<mapping name="ChoiceDisassemble" type="Button" > | ||
<button id="IK_Z"/> | ||
<button id="IK_Pad_DigitLeft" /> | ||
</mapping> | ||
</bindings> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
// Disassemble As Looting Choice by pMarK | ||
// v1.2 | ||
|
||
module DALC.Base | ||
|
||
public class DALC { | ||
private let lootingController: wref<LootingController>; | ||
private let gameInstance: GameInstance; | ||
private let dataManager: wref<InventoryDataManagerV2>; | ||
private let player: ref<PlayerPuppet>; | ||
private let blackboard: ref<IBlackboard>; | ||
private let craftingSystem: ref<CraftingSystem>; | ||
private let customChoice: InteractionChoiceData; | ||
private let settings: DALCDefaultSettings; | ||
public func Setup( | ||
lootingController: wref<LootingController>, | ||
gi: GameInstance, | ||
dataManager: wref<InventoryDataManagerV2>, | ||
referenceChoice: InteractionChoiceData | ||
) -> Void { | ||
this.lootingController = lootingController; | ||
this.gameInstance = gi; | ||
this.dataManager = dataManager; | ||
this.craftingSystem = GameInstance.GetScriptableSystemsContainer(gi).Get(n"CraftingSystem") as CraftingSystem; | ||
this.player = dataManager.GetPlayer(); | ||
this.blackboard = GameInstance.GetBlackboardSystem(gi).Get(GetAllBlackboardDefs().UI_Notifications); | ||
this.customChoice = new InteractionChoiceData(n"ChoiceDisassemble_Hold", | ||
EInputKey.IK_Z, true, GetLocalizedText("Gameplay-Devices-DisplayNames-DisassemblableItem"), | ||
referenceChoice.type, referenceChoice.data, referenceChoice.captionParts); | ||
this.SetupSettings(); | ||
} | ||
protected func SetupSettings() -> Void { | ||
let excludedQualities: array<String>; | ||
let shouldPlaySound: Bool; | ||
// ------ Settings Start ------ | ||
// Item quality strings in here prevent the disassemble option from appearing. | ||
// Possible qualities: "Common", "Uncommon", "Rare", "Epic" and "Legendary" | ||
// Default -> excludedQualities = ["Legendary"]; | ||
excludedQualities = ["Legendary"]; | ||
// Play a sound after disassemble? This is not the standard disassemble sound, just a stand-in. | ||
// Default -> shouldPlaySound = true; | ||
shouldPlaySound = true; | ||
// ------ Settings End ------ | ||
this.settings = DALCDefaultSettings.Initialize(excludedQualities, shouldPlaySound); | ||
} | ||
public func GetIsEnabled() -> Bool { | ||
return true; | ||
} | ||
public func HandleAdditionOfChoiceDisassemble(data: LootData) -> LootData { | ||
if this.GetIsEnabled() && | ||
this.CanCurrentItemBeDisassembled() && | ||
!this.lootingController.GetIsLocked() { | ||
if !this.IsDisassembleChoiceShowing(data) { | ||
ArrayPush(data.choices, this.customChoice); | ||
} | ||
this.player.RegisterInputListener(this, n"ChoiceDisassemble_Hold"); | ||
} | ||
else { | ||
this.player.UnregisterInputListener(this, n"ChoiceDisassemble_Hold"); | ||
} | ||
return data; | ||
} | ||
private func CanCurrentItemBeDisassembled() -> Bool { | ||
let inventoryItemData: InventoryItemData = this.lootingController.GetCurrentItem(); | ||
let itemData: ref<gameItemData> = InventoryItemData.GetGameItemData(inventoryItemData); | ||
//let itemRecord: = TweakDBInterface.GetItemRecord(ItemID.GetTDBID(itemData.GetID())); | ||
// Why does RPGManager.CanItemBeDisassembled() return true on Ammo? | ||
// Shards also come back as true. | ||
if Equals(itemData.GetItemType(), gamedataItemType.Con_Ammo) || itemData.HasTag(n"Shard") || itemData.HasTag(n"Quest") { | ||
return false; | ||
} | ||
if this.IsQualityExcluded(InventoryItemData.GetQuality(inventoryItemData)) { | ||
return false; | ||
} | ||
return RPGManager.CanItemBeDisassembled(this.gameInstance, itemData); | ||
} | ||
protected func IsQualityExcluded(quality: CName) -> Bool { | ||
return DALCDefaultSettings.IsQualityExcluded(this.settings, quality); | ||
} | ||
protected cb func OnAction(action: ListenerAction, consumer: ListenerActionConsumer) -> Bool { | ||
if this.GetIsEnabled() && | ||
Equals(ListenerAction.GetName(action), n"ChoiceDisassemble_Hold") && | ||
Equals(ListenerAction.GetType(action), gameinputActionType.BUTTON_HOLD_COMPLETE) { | ||
let itemData: InventoryItemData = this.lootingController.GetCurrentItem(); | ||
let itemID: ItemID = InventoryItemData.GetID(itemData); | ||
if this.CanCurrentItemBeDisassembled() { | ||
this.DisassembleItem(itemID, InventoryItemData.GetQuantity(itemData)); | ||
} | ||
} | ||
} | ||
private func DisassembleItem(itemID: ItemID, amount: Int32) -> Void { | ||
let restoredAttachments: array<ItemAttachments>; | ||
let transactionSystem: ref<TransactionSystem> = GameInstance.GetTransactionSystem(this.gameInstance); | ||
let listOfIngredients: array<IngredientData> = this.craftingSystem.GetDisassemblyResultItems(this.lootingController.GetLootOwner(), itemID, amount, restoredAttachments); | ||
let playerGameObject: ref<GameObject> = this.player as GameObject; | ||
let i: Int32 = 0; | ||
while i < ArraySize(restoredAttachments) { | ||
transactionSystem.GiveItem(playerGameObject, restoredAttachments[i].itemID, 1); | ||
i += 1; | ||
}; | ||
GameInstance.GetTelemetrySystem(this.gameInstance).LogItemDisassembled(playerGameObject, itemID); | ||
if (transactionSystem.RemoveItem(this.lootingController.GetLootOwner(), itemID, amount)) { | ||
this.ForceInteractionReactivation(); | ||
} | ||
i = 0; | ||
while i < ArraySize(listOfIngredients) { | ||
transactionSystem.GiveItem(playerGameObject, ItemID.FromTDBID(listOfIngredients[i].id.GetID()), listOfIngredients[i].quantity); | ||
i += 1; | ||
}; | ||
this.AwardExperience(listOfIngredients, amount); | ||
this.craftingSystem.UpdateBlackboard(CraftingCommands.DisassemblingFinished, itemID, listOfIngredients); | ||
if (this.ShouldPlaySound()) { | ||
this.PlayDisassembleSound(); | ||
} | ||
} | ||
private func AwardExperience(ingredients: array<IngredientData>, amount: Int32) -> Void { | ||
RPGManager.AwardXP(this.gameInstance, Cast<Float>(8), gamedataProficiencyType.Crafting); | ||
} | ||
private func IsDisassembleChoiceShowing(data: LootData) -> Bool { | ||
for choice in data.choices { | ||
if Equals(choice.localizedName, "Disassemble") { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
protected func ShouldPlaySound() -> Bool { | ||
return this.settings.playSoundAfterDisassemble; | ||
} | ||
protected func PlayDisassembleSound() -> Void { | ||
GameObject.PlaySoundEvent(this.player, n"dev_vending_machine_can_falls"); | ||
} | ||
private func ForceInteractionReactivation() -> Void { | ||
let event: ref<InteractionActivationEvent> = new InteractionActivationEvent(); | ||
event.eventType = gameinteractionsEInteractionEventType.EIET_activate; | ||
event.hotspot = this.lootingController.GetLootOwner(); | ||
event.activator = this.player; | ||
event.layerData = new InteractionLayerData(n"Loot"); | ||
this.lootingController.GetLootOwner().QueueEvent(event); | ||
} | ||
private func ShowWarningMessage(message : String) -> Void { | ||
let warningMsg: SimpleScreenMessage; | ||
warningMsg.isShown = true; | ||
warningMsg.duration = 5.00; | ||
warningMsg.message = message; | ||
this.blackboard.SetVariant(GetAllBlackboardDefs().UI_Notifications.WarningMessage, ToVariant(warningMsg), true); | ||
} | ||
} | ||
|
||
struct DALCDefaultSettings { | ||
private let excludedQualities: array<CName>; | ||
public let playSoundAfterDisassemble: Bool; | ||
public static func Initialize(qualitiesStrings: array<String>, playSound: Bool) -> DALCDefaultSettings { | ||
let excludedQualities: array<CName>; | ||
let size: Int32 = ArraySize(qualitiesStrings); | ||
let i: Int32; | ||
ArrayGrow(excludedQualities, size); | ||
while i < size { | ||
excludedQualities[i] = StringToName(qualitiesStrings[i]); | ||
i += 1; | ||
} | ||
return new DALCDefaultSettings(excludedQualities, playSound); | ||
} | ||
public static func IsQualityExcluded(self: DALCDefaultSettings, quality: CName) -> Bool { | ||
return ArrayContains(self.excludedQualities, quality); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Disassemble As Looting Choice by pMarK | ||
// v1.2 | ||
|
||
module DALC.Overrides | ||
import DALC.Base.DALC | ||
|
||
@if(ModuleExists("DALC.Menu")) | ||
import DALC.Menu.DALCWithMenu | ||
|
||
@addField(LootingController) | ||
private let disassembleAsLootingOptionMod: ref<DALC>; | ||
|
||
@wrapMethod(LootingController) | ||
private final func RefreshChoicesPool(choices: script_ref<array<InteractionChoiceData>>) -> Void { | ||
if !IsDefined(this.disassembleAsLootingOptionMod) { | ||
this.InitializeDALC(); | ||
this.disassembleAsLootingOptionMod.Setup( | ||
this, | ||
this.m_gameInstance, | ||
this.m_dataManager, | ||
this.m_currendData.choices[0]); | ||
} | ||
this.m_currendData = this.disassembleAsLootingOptionMod.HandleAdditionOfChoiceDisassemble(this.m_currendData); | ||
wrappedMethod(this.m_currendData.choices); | ||
} | ||
|
||
@if(ModuleExists("DALC.Menu")) | ||
@addMethod(LootingController) | ||
private func InitializeDALC() -> Void { | ||
this.disassembleAsLootingOptionMod = new DALCWithMenu(); | ||
} | ||
@if(!ModuleExists("DALC.Menu")) | ||
@addMethod(LootingController) | ||
private func InitializeDALC() -> Void { | ||
this.disassembleAsLootingOptionMod = new DALC(); | ||
} | ||
|
||
@addMethod(LootingController) | ||
public func GetIsLocked() -> Bool { | ||
return this.m_isLocked; | ||
} | ||
|
||
@addMethod(LootingController) | ||
public func GetCurrentItem() -> InventoryItemData { | ||
let itemData: ref<gameItemData> = this.m_dataManager.GetExternalGameItemData(this.m_currendData.ownerId, this.m_currendData.itemIDs[this.m_currendData.currentIndex]); | ||
return this.m_dataManager.GetInventoryItemData(this.GetLootOwner(), itemData); | ||
} | ||
|
||
@addMethod(LootingController) | ||
public func GetLootOwner() -> wref<GameObject> { | ||
return GameInstance.FindEntityByID(this.m_gameInstance, this.m_currendData.ownerId) as GameObject; | ||
} | ||
|
||
@addMethod(InventoryDataManagerV2) | ||
public func GetPlayer() -> wref<PlayerPuppet> { | ||
return this.m_Player; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Disassemble As Looting Choice by pMarK | ||
// v1.2 | ||
|
||
module DALC.Menu | ||
import DALC.Base.DALC | ||
|
||
public class DALCWithMenu extends DALC { | ||
private let menuSettings: ref<DALCMenuSettings>; | ||
protected func SetupSettings() -> Void { | ||
this.menuSettings = new DALCMenuSettings(); | ||
ModSettings.RegisterListenerToClass(this.menuSettings); // Hard "Mod Settings" dependency | ||
} | ||
public func GetIsEnabled() -> Bool { | ||
return this.menuSettings.IsEnabled; | ||
} | ||
protected func ShouldPlaySound() -> Bool { | ||
return this.menuSettings.ShouldPlaySound; | ||
} | ||
protected func IsQualityExcluded(quality: CName) -> Bool { | ||
return !this.GetShowSettingByQuality(quality); | ||
} | ||
private func GetShowSettingByQuality(quality: CName) -> Bool { | ||
if (Equals(quality, n"Common")) { | ||
return this.menuSettings.ShowForCommon; | ||
} | ||
if (Equals(quality, n"Uncommon")) { | ||
return this.menuSettings.ShowForUncommon; | ||
} | ||
if (Equals(quality, n"Rare")) { | ||
return this.menuSettings.ShowForRare; | ||
} | ||
if (Equals(quality, n"Epic")) { | ||
return this.menuSettings.ShowForEpic; | ||
} | ||
return this.menuSettings.ShowForLegendary; | ||
} | ||
} | ||
|
||
public class DALCMenuSettings { | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Main") | ||
@runtimeProperty("ModSettings.displayName", "Enabled") | ||
@runtimeProperty("ModSettings.description", "Enable/Disable mod.") | ||
public let IsEnabled: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Main") | ||
@runtimeProperty("ModSettings.displayName", "Play Sound") | ||
@runtimeProperty("ModSettings.description", "If this is enabled a sound will be played when you disassemble an item.") | ||
public let ShouldPlaySound: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Show Disassemble By Quality") | ||
@runtimeProperty("ModSettings.displayName", "Common") | ||
@runtimeProperty("ModSettings.description", "Should the disassemble option appear for Common items?") | ||
public let ShowForCommon: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Show Disassemble By Quality") | ||
@runtimeProperty("ModSettings.displayName", "Uncommon") | ||
@runtimeProperty("ModSettings.description", "Should the disassemble option appear for Uncommon items?") | ||
public let ShowForUncommon: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Show Disassemble By Quality") | ||
@runtimeProperty("ModSettings.displayName", "Rare") | ||
@runtimeProperty("ModSettings.description", "Should the disassemble option appear for Rare items?") | ||
public let ShowForRare: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Show Disassemble By Quality") | ||
@runtimeProperty("ModSettings.displayName", "Epic") | ||
@runtimeProperty("ModSettings.description", "Should the disassemble option appear for Epic items?") | ||
public let ShowForEpic: Bool = true; | ||
@runtimeProperty("ModSettings.mod", "D.A.L.C.") | ||
@runtimeProperty("ModSettings.category", "Show Disassemble By Quality") | ||
@runtimeProperty("ModSettings.displayName", "Legendary") | ||
@runtimeProperty("ModSettings.description", "Should the disassemble option appear for Legendary items?") | ||
public let ShowForLegendary: Bool = false; | ||
} |