From e331108089dbf3eb0f8821c9966c7e94180801a6 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Sun, 13 Feb 2022 03:15:13 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + Pickup Helper.esp | Bin 0 -> 2611 bytes README.md | 9 + Scripts/ETAxPlayerAliasScript.pex | Bin 0 -> 6436 bytes Scripts/PRKF_ETAxTakePerk_02000805.pex | Bin 0 -> 1882 bytes Source/Scripts/ETAxPlayerAliasScript.psc | 194 ++++++++++++++++++ Source/Scripts/PRKF_ETAxTakePerk_02000805.psc | 88 ++++++++ 7 files changed, 292 insertions(+) create mode 100644 .gitignore create mode 100644 Pickup Helper.esp create mode 100644 README.md create mode 100644 Scripts/ETAxPlayerAliasScript.pex create mode 100644 Scripts/PRKF_ETAxTakePerk_02000805.pex create mode 100644 Source/Scripts/ETAxPlayerAliasScript.psc create mode 100644 Source/Scripts/PRKF_ETAxTakePerk_02000805.psc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9dfed9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/meta.ini diff --git a/Pickup Helper.esp b/Pickup Helper.esp new file mode 100644 index 0000000000000000000000000000000000000000..d1455c26bf3ae70375b6a85420848f05218077e7 GIT binary patch literal 2611 zcmb7F%}(1u5FRIi1PD+nkoqH4xk0501p*aPRZ%y#A;Lh2owTQ-2rppeSGJ>+Q+a|O zdZ9?JlzDbFu3-AA*ILDJZ%JwN5*;$?9$9!M1AI z6JXU&Jh!pP{03;Mt){|I5N?;-PBmbCwhKFUB>@V;H%jH=cY2$<&&gV&G*Re#UMwM= z5_Qm)t`)Rfpxf$e%BS4cSiO1z24<+hp<$BS@gJX_lKDbtp6D^3k<3d~$L;u`y)Wzm z-sk1;$sT(V{snW7jsw$exIwS^=`*V8E0(ucwrt8Gs*1ipQrRdrcn^xDEn}a~W3<1YUCw5+YuQyu!fmLqrql8Y z0c-4ftk67ag|qc%b_{Mbi0QCtV!~-`#1Wd6La0r*QLS&f4ijVb8-x6FtWsdM4r*<@ zMFe;p9mWRLlcbQK41!F6;Z=_stQqX*a)ciiy|hM*4@8e&`hJWJ91NBcSz0BohIO5b z{|_v?UZxv=plb=8TheqZkIB%l0!Iz+F9oMZkJGe~E)G*;G1MSN$=jNmK@7?1`WLhk z^a~9=&rzm;X$xNe9F?t>*&qB4#zniGgGNd1!4D7>UY`6@C7csZ}IP5tMsnF|RuVNQQ literal 0 HcmV?d00001 diff --git a/README.md b/README.md new file mode 100644 index 0000000..def42bf --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +## Pickup Helper + +Picks up loose gold, arrows, ingredients, flora, leather, hides, and ingots of the same type. + +Inspired by dylbill's [Take All Loose Gold and Arrows](https://www.nexusmods.com/skyrimspecialedition/mods/22680), but approaches certain tasks differently. Made mainly for personal use, hence the lack of customization. + +- Pickup Helper is based on a perk with the Activate entrypoint instead of using [OnItemAdded](https://ck.uesp.net/wiki/OnItemAdded_-_ObjectReference). +- Picks up wider range of items, becoming a simple autoloot helper as well. +- Does not rely on pre-defined item lists and uses automatic detection more extensively. diff --git a/Scripts/ETAxPlayerAliasScript.pex b/Scripts/ETAxPlayerAliasScript.pex new file mode 100644 index 0000000000000000000000000000000000000000..db1f1a00c48db6c8b3ecb3255af5323d6b5155f9 GIT binary patch literal 6436 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 literal 0 HcmV?d00001 diff --git a/Scripts/PRKF_ETAxTakePerk_02000805.pex b/Scripts/PRKF_ETAxTakePerk_02000805.pex new file mode 100644 index 0000000000000000000000000000000000000000..89ffa49130790b01193696fc4048fe1dce5773aa GIT binary patch literal 1882 zcmZ`&ZByGu5Pr@!eggwF4kWatPMVYwNaB}3h)SEm9h)-A1P{>kBXgAwqgvK^PI8F< zUBC8E^iQ;(I@6i%on$NqSL=~?pS|6Ec5n61FTekpPJw|Q{_o#DHoB*8I~VQq!%yeD zFSM=BV3$o+iQK7H2x5pS^m|521Uebof3c=i(dtwW7u#D2nP)-i8O-*H1%`rJeI%5@y!BcnUPl4W&0 zJ{Ia!TwZ+S3Uk~Jr9ydvpV`VChQ@VIg#6RcoaUa(gTT13Zdo6M??`nViov1p4!HM| z>j)E)>x=QVR1Ov`>z%awL)Y#bM{(c=w*2)sVTZV%OmL#avEP$X#TCoab3ar{UcYmL z2+UtfHSoyNB(?iUdd`h^A&H=LD;x_^uTf7Z+;oo0tPYT$P)2#`pAbamz4Qg_+SIe5#FKW zCrY=6*wvgUHDu31<@!Brc1FIf@3$IW@vy2yI8uHdB4u@gtQl4W zKA0#utdnXI=Lr3LYOLW4${2f=@g>!XjYVuw!q_O|D=HHk6;!95RYG-Vc|45#(I~#g zV@j366MTbBa-|j-o-nMgF?`Fg%&@7)n<8+I(NJc_ZY5&37}hBE=`@xxY|&(9Ms6n} zw;3MXiQGnJcH~YXa)+UOhwl#YP2m}yM?=?dw$AW^?r|oSS|VYMp>l^xjaF(#WEypf zY{b!73TrYvVyK(7EHN}lU!^~7r|)EKRLpz{f0-DW#x`iNA7WP%*Soeyz0hqCq?5d2 z*pKf9RO1Et34NVF>8fY4wP>vm5^TRWY%RmK$Y9Zr*cv-SDWhf%jGN3K5+oT840-k+ DsqS69 literal 0 HcmV?d00001 diff --git a/Source/Scripts/ETAxPlayerAliasScript.psc b/Source/Scripts/ETAxPlayerAliasScript.psc new file mode 100644 index 0000000..febde44 --- /dev/null +++ b/Source/Scripts/ETAxPlayerAliasScript.psc @@ -0,0 +1,194 @@ +Scriptname ETAxPlayerAliasScript extends ReferenceAlias + +int iFloraCount = 0 +int iArrowCount = 0 + +event OnInit() + PlayerRef.AddPerk(ETAxTakePerk) + RegisterForSingleUpdate(10.0) +endevent + +event OnPlayerLoadGame() + RegisterForSingleUpdate(10.0) +endevent + +event OnUpdate() + ScanPouches() + ScanArrows() +endevent + +function ScanArrows() + + Form[] aItems = PO3_SKSEfunctions.GetAllForms(42) ; ammo + int i = aItems.Length + + if iArrowCount == i + return + endif + + iArrowCount = i + + Projectile arrowProjectile + ETAxArrowList.Revert() + + while i > 0 + i -= 1 + if aItems[i].IsPlayable() + + ETAxArrowList.AddForm(aItems[i]) + + arrowProjectile = (aItems[i] as Ammo).GetProjectile() + + if arrowProjectile && ! ETAxArrowList.HasForm(arrowProjectile) + ETAxArrowList.AddForm(arrowProjectile) + endif + + endif + endwhile + +endfunction + +function ScanPouches() + + Form[] aItems = PO3_SKSEfunctions.GetAllForms(39) ; flora + int i = aItems.Length + + if iFloraCount == i + return + endif + + iFloraCount = i + + SoundDescriptor refSound + ETAxGoldList.Revert() + + While i > 0 + i -= 1 + refSound = (aItems[i] as Flora).GetHarvestSound() + if refSound && ETAxPouchSounds.Find(refSound) != -1 && ! ETAxGoldList.HasForm(aItems[i]) + ETAxGoldList.AddForm(aItems[i]) + endif + Endwhile + +endfunction + +function TakeByArray(ObjectReference[] aRefs, bool bCheckWeight = false) + + float fDelay = ETAxPickUpDelay.Value + int i = aRefs.Length + + While i > 0 + i -= 1 + if aRefs[i].IsEnabled() && aRefs[i].Is3DLoaded() + if fDelay > 0 + Utility.wait(fDelay) + endif + if ! bCheckWeight || aRefs[i].GetBaseObject().GetWeight() <= ETAxWeightLimit.Value + aRefs[i].Activate(PlayerRef) + endif + endif + Endwhile + +endfunction + +function PickFloraByType(Form rBase) + + int iType = rBase.GetType() + Form pickedIngredient + + if iType == 38 ; tree + pickedIngredient = (rBase as TreeObject).GetIngredient() + elseif iType == 39 ; flora + pickedIngredient = (rBase as Flora).GetIngredient() + else + return + endif + + ObjectReference[] aRefs = PO3_SKSEfunctions.FindAllReferencesOfFormType(PlayerRef, iType, ETAxPickUpRadius.Value * 1.5) + int i = aRefs.Length + float fDelay = ETAxPickUpDelay.Value + Form refIngredient + + while i > 0 + i -= 1 + + if aRefs[i].GetBaseObject() == rBase + + if ! aRefs[i].IsHarvested() && aRefs[i].IsEnabled() && aRefs[i].Is3DLoaded() + if fDelay > 0 + Utility.wait(fDelay) + endif + aRefs[i].Activate(PlayerRef) + endif + + else + + if iType == 38 ; tree + refIngredient = (aRefs[i].GetBaseObject() as TreeObject).GetIngredient() + else + refIngredient = (aRefs[i].GetBaseObject() as Flora).GetIngredient() + endif + + if refIngredient == pickedIngredient && ! aRefs[i].IsHarvested() && aRefs[i].IsEnabled() && aRefs[i].Is3DLoaded() + if fDelay > 0 + Utility.wait(fDelay) + endif + aRefs[i].Activate(PlayerRef) + endif + + endif + + endwhile + +endfunction + +function PickFloraByTypeIdAndIngredient(int iType, Form fIngredient) + + ObjectReference[] aRefs = PO3_SKSEfunctions.FindAllReferencesOfFormType(PlayerRef, iType, ETAxPickUpRadius.Value * 1.5) + int i = aRefs.Length + float fDelay = ETAxPickUpDelay.Value + Form refIngredient + + while i > 0 + i -= 1 + + if iType == 38 ; tree + refIngredient = (aRefs[i].GetBaseObject() as TreeObject).GetIngredient() + else + refIngredient = (aRefs[i].GetBaseObject() as Flora).GetIngredient() + endif + + if refIngredient == fIngredient && ! aRefs[i].IsHarvested() && aRefs[i].IsEnabled() && aRefs[i].Is3DLoaded() + if fDelay > 0 + Utility.wait(fDelay) + endif + aRefs[i].Activate(PlayerRef) + endif + + endwhile + +endfunction + +function TakeByFormOrList(Form formOrList) + TakeByArray(PO3_SKSEfunctions.FindAllReferencesOfType(PlayerRef, formOrList, ETAxPickUpRadius.Value)) +endfunction + +function TakeByKeyword(Form keywordOrList, bool bCheckWeight = false) + TakeByArray(PO3_SKSEfunctions.FindAllReferencesWithKeyword(PlayerRef, keywordOrList, ETAxPickUpRadius.Value, false), bCheckWeight) +endfunction + +function TakeByFormType(int iFormType) + TakeByArray(PO3_SKSEfunctions.FindAllReferencesOfFormType(PlayerRef, iFormType, ETAxPickUpRadius.Value)) +endfunction + +Actor Property PlayerRef Auto + +Perk Property ETAxTakePerk Auto + +GlobalVariable Property ETAxPickUpDelay Auto +GlobalVariable Property ETAxPickUpRadius Auto +GlobalVariable Property ETAxWeightLimit Auto + +FormList Property ETAxPouchSounds Auto +FormList Property ETAxGoldList Auto +FormList Property ETAxArrowList Auto diff --git a/Source/Scripts/PRKF_ETAxTakePerk_02000805.psc b/Source/Scripts/PRKF_ETAxTakePerk_02000805.psc new file mode 100644 index 0000000..2f2494c --- /dev/null +++ b/Source/Scripts/PRKF_ETAxTakePerk_02000805.psc @@ -0,0 +1,88 @@ +;BEGIN FRAGMENT CODE - Do not edit anything between this and the end comment +;NEXT FRAGMENT INDEX 36 +Scriptname PRKF_ETAxTakePerk_02000805 Extends Perk Hidden + +;BEGIN FRAGMENT Fragment_33 +Function Fragment_33(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +PlayerScript.TakeByKeyword(VendorItemAnimalHide, true) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_15 +Function Fragment_15(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +; Ingredients +; This fails on dropped items, looking for a proper way to detect them +Form rBase = akTargetRef.GetBaseObject() +if rBase + PlayerScript.TakeByFormOrList(rBase) + ;PlayerScript.PickFloraByTypeIdAndIngredient(38, rBase) ; tree + ;PlayerScript.PickFloraByTypeIdAndIngredient(39, rBase) ; flora +else + PlayerScript.TakeByFormType(30) +endif +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_6 +Function Fragment_6(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +; Arrows and projectiles +PlayerScript.TakeByFormOrList(ETAxArrowList) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_3 +Function Fragment_3(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +PlayerScript.TakeByFormOrList(ETAxGoldList) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_12 +Function Fragment_12(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +PlayerScript.TakeByKeyword(VendorItemOreIngot, true) +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_18 +Function Fragment_18(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +; Flora +if ! akTargetRef.IsActivationBlocked() + PlayerScript.PickFloraByType(akTargetRef.GetBaseObject()) +endif +;END CODE +EndFunction +;END FRAGMENT + +;BEGIN FRAGMENT Fragment_31 +Function Fragment_31(ObjectReference akTargetRef, Actor akActor) +;BEGIN CODE +PlayerScript.TakeByFormOrList(Lockpick) +;END CODE +EndFunction +;END FRAGMENT + +;END FRAGMENT CODE - Do not edit anything between this and the begin comment + +ETAxPlayerAliasScript Property PlayerScript Auto + +Actor Property PlayerRef Auto + +FormList Property ETAxGoldList Auto + +FormList Property ETAxArrowList Auto + +Keyword Property VendorItemOreIngot Auto + +MiscObject Property Lockpick Auto + +Keyword Property VendorItemAnimalHide Auto