lofgren Posted January 16, 2017 Share Posted January 16, 2017 Would it not be preferable to move the extra weapons to a container somewhere and then move them back? Seems less complicated than dropping them all. Link to comment Share on other sites More sharing options...
Masterofnet Posted January 16, 2017 Author Share Posted January 16, 2017 (edited) Your code is also not putting back the actual items taken from the player for the unpoisoned ones. In 99.9% of the cases that's fine, but if you're going for absolute safety you need return the items that were dropped UnpoisonedStackRef instead of Poisoned as the first parameter. (And the Disable call has to be done on a separate line.) Agreed The exact same weapons need to be put back, but when I put the stack back in inventory and dropped the weapons one at a time they all disappeared until only one was left because they all had the same object reference. The new version solved both of these issues. For some reason most of my post was just deleted. So here is the short version. Check out this new script. It uses remove item and a chest. lofgren - Yes and it works well. A couple of updates. The weapon issue with drop has nothing to do with persistence. I was also able to use Silver Swords so it is more that just the script. As far as quest items, which are all persistent while the quest is running, it works fine with all I have attempted other than the Ebony Blade. However, Drop does not work with the Ebony Blade so I have updated the script and it works fine. Just the Weapon Ebony Blade also works fine, but the quest object does not. If anyone knows about weapons other than the Ebony or Bloodskal Blade that do not work with weapon racks please let me know. Scriptname PlayerAliasPotion extends ReferenceAlias Potion Property ThePotion Auto ObjectReference UnpoisonedStackRef ObjectReference PWeaponRef ObjectReference PotionRef ObjectReference Property chest Auto ObjectReference Property DA08EbonyBladeREF Auto ReferenceAlias Property PotionAlias Auto ReferenceAlias Property PoisonedWeaponRef Auto Int Distance Int UnpoisonedCount Weapon Poisoned Actor PlayerRef Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) AddInventoryEventFilter(ThePotion) PlayerRef = Self.GetReference() As Actor PotionRef = PotionAlias.GetReference() If PlayerRef.GetItemCount(ThePotion) Else Distance = PlayerRef.GetDistance(PotionRef) as Int If akDestContainer akDestContainer.RemoveItem(PotionRef, 1 , False, PlayerRef ) Debug.Notification("You can not drop this!") Else If Distance < 4000 PlayerRef.AddItem(PotionRef,1,True) Debug.Notification("You can not drop this!") Else WeaponPoisoned() EndIf EndIf EndIf EndEvent Function WeaponPoisoned() Poisoned = (PlayerRef.GetEquippedWeapon()) If Poisoned == DA08EbonyBladeREF.GetBaseObject() As Weapon PoisonedWeaponRef.ForceRefTo(DA08EbonyBladeREF) Else UnpoisonedCount = PlayerRef.GetItemCount(Poisoned) - 1 PlayerRef.RemoveItem(Poisoned, 1, True, Chest) PoisonedWeaponRef.ForceRefTo(Chest.DropObject(Poisoned)) If UnpoisonedCount > 0 PlayerRef.RemoveItem(Poisoned, UnpoisonedCount, True, Chest) EndIf PWeaponRef = PoisonedWeaponRef.GetReference() PlayerRef.AddItem(PWeaponRef, 1, True) PlayerRef.EquipItem(PWeaponRef.GetBaseObject(), False, True) If UnpoisonedCount > 0 Chest.RemoveItem(Poisoned, UnpoisonedCount, True, PlayerRef) EndIf EndIf EndFunction Edited January 17, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Masterofnet Posted January 17, 2017 Author Share Posted January 17, 2017 (edited) I was reading up on this and there may some other weapons that can have a problem with drop based on weapon rack reports. So I came up with this and believe it or not it works perfectly. When testing this script I made a very interesting discovery. I can not get a weapon to not be a objectreference when it is dropped from the player. The purpose of this script is to get.1. When the potion is applied to a Weapon2. When the target is poisoned and who they are. 3. The exact weapon and type of weapon that was poisoned.4. If the potion was lost - Not used on a target and not able to be reapplied. For example the potion was put on a bow and the shot missed. Here is the final version of the script. This script goes on a playerAlias Scriptname B2CraPlayerAliasPotion extends ReferenceAlias B2CquWildManQuestScript Property B2CquWildMan Auto ObjectReference PotionRef ObjectReference Property B2CcoExtrasChestRef Auto ObjectReference Property B2CcoPoisonedChestRef Auto ReferenceAlias Property PotionAlias Auto B2CraPoisonedWeapon Property PoisonedWeaponAlias Auto Int UnpoisonedCount Weapon Poisoned EVENT OnInit() Form PO = PotionAlias.GetReference().GetBaseObject() AddInventoryEventFilter(PO) ENDEVENT Event OnItemRemoved(Form Item, int NA, ObjectReference PoisonedWeapon, ObjectReference akDestContainer) OnjectReference SelfRef = GetReference() If SelfRef.GetItemCount(Item) Return EndIf If akDestContainer akDestContainer.RemoveItem(PotionRef, 1 , False, SelfRef ) B2CquWildMan.B2CmsOblivionChestNoDrop.Show() Return EndIf Int Distance = SelfRef.GetDistance(PotionRef) as Int If Distance < 4000 SelfRef.AddItem(PotionRef,1,True) B2CquWildMan.B2CmsOblivionChestNoDrop.Show() Return EndIf Poisoned = (SelfRef As Actor).GetEquippedWeapon() UnpoisonedCount = SelfRef.GetItemCount(Poisoned) - 1 If UnpoisonedCount > 0 SelfRef.RemoveItem(Poisoned, 1, True, B2CcoPoisonedChestRef) SelfRef.RemoveItem(Poisoned, UnpoisonedCount, True, B2CcoExtrasChestRef) B2CcoPoisonedChestRef.RemoveItem(Poisoned, 1, True, SelfRef) EndIf GoToState("OneWeapon") EndEvent State OneWeapon Event OnBeginState() AddInventoryEventFilter(Poisoned) GetReference().DropObject(Poisoned) EndEvent Event OnItemRemoved(Form Item, int NA, ObjectReference PoisonedWeapon, ObjectReference akDestContainer) Actor PlayerRef = GetReference() As Actor GoToState("Done") PoisonedWeaponAlias.ForceRefTo(PoisonedWeapon) PlayerRef.AddItem(PoisonedWeapon, 1, True) PlayerRef.EquipItem(PoisonedWeapon.GetBaseObject(), False, True) If UnpoisonedCount > 0 B2CcoExtrasChestRef.RemoveItem(Poisoned, UnpoisonedCount, True, PlayerRef) EndIf PoisonedWeaponAlias.SetWeapon() RemoveAllInventoryEventFilters() EndEvent EndState State Done Event OnItemRemoved(Form Item, int NA, ObjectReference PoisonedWeapon, ObjectReference akDestContainer) EndEvent EndState This Script goes on the Potion's Magic Effect Scriptname B2CameKrosisPotion extends activemagiceffect Import Utility Import Debug Int Property AcquireItemObj Auto Int Property PotionLostObj Auto Int Property KillTargetObj Auto Int Property FailedToKillTargetObj Auto ReferenceAlias Property PoisonedAlias Auto B2CraPoisonedWeapon Property PoisonedWeaponAlias Auto Quest Property QST Auto Actor Poisoned ActorBase PoisonedBase Event OnEffectStart(Actor Target, Actor Caster) PoisonedWeaponAlias.TargetVar = True Poisoned = PoisonedAlias.GetReference() as Actor PoisonedBase = Poisoned.GetActorBase() If Target == Poisoned PoisonedWeaponAlias.ClearWeapon() If PoisonedBase.IsInvulnerable() PoisonedBase.SetInvulnerable(False) EndIf QST.SetObjectiveDisplayed(KillTargetObj) Int WaitTime = 180 While !Target.IsDead() && WaitTime > 0 Wait(30.0) WaitTime -= 30 If WaitTime == 150 Notification("You Have 150 Seconds") ElseIf WaitTime == 120 Notification("120 Seconds") ElseIf WaitTime == 90 Notification("90 Seconds") ElseIf WaitTime == 60 Notification("60 Seconds") Else Notification("30 Seconds") EndIf EndWhile Else QST.SetObjectiveFailed(AcquireItemObj) QST.SetObjectiveDisplayed(PotionLostObj) Wait(5.0) Game.GetPlayer().Kill() EndIf PoisonedWeaponAlias.TargetVar = False EndEvent Event OnEffectFinish(Actor Target, Actor Caster) If Target.IsDead() Else If QST.GetCurrentStageID() == AcquireItemObj Else If PoisonedBase.IsInvulnerable()==False PoisonedBase.SetInvulnerable() EndIf EndIf QST.SetObjectiveFailed(AcquireItemObj) QST.SetObjectiveFailed(KillTargetObj) QST.SetObjectiveDisplayed(FailedToKillTargetObj) Wait(5.0) Game.GetPlayer().Kill() EndIf EndEvent This Script goes on the Poisoned Weapons Alias Scriptname B2CraPoisonedWeapon extends ReferenceAlias B2CquWildManQuestScript Property B2CquWildMan Auto Keyword Property WeapTypeBow Auto Int Property AcquireItemObj Auto Int Property PotionLostObj Auto Bool Property TargetVar Auto Hidden Weapon SelfPoisoned Actor PlayerRef Event OnEquipped(Actor akActor) RegisterForAnimationEvent(PlayerRef, "arrowRelease") EndEvent Event OnUnequipped(Actor akActor) UnRegisterForAnimationEvent(PlayerRef, "arrowRelease") EndEvent Event OnAnimationEvent(ObjectReference akSource, string asEventName) If akSource == PlayerRef && asEventName == "arrowRelease" Utility.Wait(4) If TargetVar==False Quest QST = GetOwningQuest() QST.SetObjectiveFailed(AcquireItemObj) QST.SetObjectiveDisplayed(PotionLostObj) Utility.Wait(5) PlayerRef.Kill() Else UnRegisterForAnimationEvent(PlayerRef, "arrowRelease") Clear() EndIf EndIf EndEvent Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) ObjectReference QuestItem = GetReference() PlayerRef = Game.GetPlayer() If AkNewContainer If AkNewContainer == PlayerRef Return Else AkNewContainer.RemoveItem(QuestItem, 1 , False, PlayerRef ) B2CquWildMan.B2CmsOblivionChestNoDrop.Show() EndIf Else PlayerRef.AddItem(QuestItem, AbSilent = true) B2CquWildMan.B2CmsOblivionChestNoDrop.Show() EndIf EndEvent State NoBow Event OnEquipped(Actor akActor) EndEvent Event OnUnequipped(Actor akActor) EndEvent EndState Function ClearWeapon() If GetState() == "NoBow" Clear() EndFunction Function SetWeapon() SelfPoisoned = QuestItem.GetBaseObject() As Weapon If SelfPoisoned.HasKeyword(WeapTypeBow) RegisterForAnimationEvent(PlayerRef, "arrowRelease") Else GoToState("NoBow") EndIf EndFunction Edited January 27, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
ReDragon2013 Posted January 25, 2017 Share Posted January 25, 2017 (edited) .. Edited March 6, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
Masterofnet Posted January 25, 2017 Author Share Posted January 25, 2017 (edited) what does it mean: "B2C" infront of your script names?Nothing I actually use something else but I want to keep it secret for now. It would be the 3 letters I identify my mod with. 1 "B2CquWildMan" I guess, you forgot the quest scriptThat quest script is not the quest script for this quest. It is a quest that I use to manage all my other quests. VM quest variables and other things. Like reducing the properties I have on a script. By simply adding that Quest Script I have access to all kinds of things so I can significantly modify a large # of scripts without having to refill any properties. 2) What formID have the chests, what is the container object?I have a cell I made that I keep the things for my quests in. That is where the chests are. They are empty small draugr chests. 3) I found script code issue!Yes, I made a couple of small changes to the scripts today and found that. It is just = now. 4) Scriptname B2CameKrosisPotion extends activemagiceffectAll it does is make an invulnerable NPC vulnerable for a set amount of time. It is the effect for the Potion. 5) You wrote: "I can not get a weapon to not be a objectreference when it is dropped from the player."No matter how I add an item to the players inventory, when I drop it and use OnItemRemoved to get the form or object reference, the item always has an object reference. Edited January 25, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
ReDragon2013 Posted January 26, 2017 Share Posted January 26, 2017 (edited) .. Edited March 6, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
Masterofnet Posted January 26, 2017 Author Share Posted January 26, 2017 (edited) A couple of things. Remove item will always remove the equipped weapon first. That is why you must remove it and then the other weapons. Also the potion being < 4000) from the player is a way of determining if it has been dropped or used on a weapon. If there is no new container and the distance is > 4000 the potion has been applied to a weapon. This is done because if you attempt to poison a weapon and decide not to, or you attempt to use a potion and do not have a weapon equipped, the on item removed event will fire but the potion will still be in the players inventory. IF (selfRef.GetItemCount(akBaseItem) > 0) RETURN ; - STOP - /1 player has still left one potion ENDIF Some interesting work as usual. I will need time to go over it all. Redragon , Here is my update of the Player Alias Script. I don't change the names to much because it effects auto filling of the properties. This is in my option a huge improvement. Thanks The first script is another script needed on the player alias. Scriptname B2CraPlayerAliasPotionCraft extends ReferenceAlias B2CquWildManQuestScript Property B2CquWildMan Auto ReferenceAlias[] Property RefArray Auto Int Property StageToSet Auto Form Poison Event OnItemAdded(Form Item, int IC, ObjectReference ItemRef, ObjectReference NU) GoToState("Done") ObjectReference PlayerRef = B2CquWildMan.PlayerRef Int Count = B2CquWildMan.ArrayCount(RefArray) Int i = 0 While i < Count If Item == RefArray[i].GetReference().GetBaseObject() i = Count RemoveInventoryEventFilter(Item ) PlayerRef.RemoveItem(Item,1,True) PlayerRef.AddItem(RefArray[i].GetReference(),1,True) RefArray[i] = none B2CquWildMan.ArraySort(RefArray) If Item == Poison GetOwningQuest().SetStage(StageToSet) ((Self as ReferenceAlias) as B2CraPlayerAliasPotion).SetUp() Return EndIf Else i = i + 1 EndIf EndWhile If Count > 1 GoToState("") EndIf EndEvent Auto State Done Event OnItemAdded(Form Item, int aiItemCount, ObjectReference ItemRef, ObjectReference NU) EndEvent EndState Function SetUp() Poison = RefArray[0].GetReference().GetBaseObject() Int i While i < RefArray.Length AddInventoryEventFilter(RefArray[i].GetReference().GetBaseObject()) i = i + 1 EndWhile GoToState("") EndFunction Function Reset() GoToState("") EndFunction ;================================Functions On B2WildManQuestScript========================== bool function ArraySort(ReferenceAlias[] RefArray, Int i = 0) ;Author: Chesko updated by Masterofnet bool bFirstNoneFound = false int IFirstNonePos = i while i < RefArray.Length If !RefArray[i] ; RefArray[i] == none If !bFirstNoneFound ;bFirstNoneFound == false bFirstNoneFound = true IFirstNonePos = i i = i + 1 Else i = i + 1 EndIf Else If bFirstNoneFound ;bFirstNoneFound == true ;check to see If it is a couple of blank entries in a row If RefArray[i] ;!(RefArray[i] == none) ;notIfication("Moving element " + i + " to index " + IFirstNonePos) RefArray[IFirstNonePos] = RefArray[i] RefArray[i] = none ;Call this function recursively until it Returns ArraySort(RefArray, IFirstNonePos + 1) Return true Else i = i + 1 EndIf Else i = i + 1 EndIf EndIf EndWhile Return false EndFunction int function ArrayCount(ReferenceAlias[] RefArray) ;Author: Chesko updated by Masterofnet int i = 0 int myCount = 0 while i < RefArray.Length If RefArray[i] ;RefArray[i] != none myCount += 1 i = i + 1 Else i = i + 1 EndIf EndWhile Return myCount EndFunction Player Alias Scriptname B2CraPlayerAliasPotion extends ReferenceAlias B2CquWildmanQuestScript Property B2CquWildman Auto ObjectReference Property B2CcoExtrasChestRef Auto ObjectReference Property B2CcoPoisonedChestRef Auto B2CraPoisonedWeapon Property PoisonedWeaponAlias Auto ReferenceAlias Property PotionAlias Auto Int UnpoisonedCount Event OnItemRemoved(Form Item, int NA, ObjectReference ItemRef, ObjectReference akDestContainer) objectReference SelfRef = GetReference() If SelfRef.GetItemCount(Item) Return EndIf If akDestContainer akDestContainer.RemoveItem(ItemRef, 1 , False, SelfRef ) B2CquWildman.B2CmsOblivionChestNoDrop.Show() Return EndIf If SelfRef.GetDistance(ItemRef) < 20000 SelfRef.AddItem(ItemRef,1,True) B2CquWildman.B2CmsOblivionChestNoDrop.Show() Return EndIf Weapon Poisoned = (SelfRef As Actor).GetEquippedWeapon() UnpoisonedCount = SelfRef.GetItemCount(Poisoned) - 1 If UnpoisonedCount > 0 SelfRef.RemoveItem(Poisoned, 1, True, B2CcoPoisonedChestRef) SelfRef.RemoveItem(Poisoned, UnpoisonedCount, True, B2CcoExtrasChestRef) B2CcoPoisonedChestRef.RemoveItem(Poisoned, 1, True, SelfRef) EndIf GoToState("OneWeapon") AddInventoryEventFilter(Poisoned) RemoveInventoryEventFilter(Item) SelfRef.DropObject(Poisoned) EndEvent State OneWeapon Event OnItemRemoved(Form Item, int NA, ObjectReference ItemRef, ObjectReference akDestContainer) ObjectReference SelfRef = GetReference() GoToState("Done") PoisonedWeaponAlias.ForceRefTo(ItemRef) SelfRef.AddItem(ItemRef, 1, True) (SelfRef As Actor).EquipItem(ItemRef.GetBaseObject(), False, True) If UnpoisonedCount > 0 B2CcoExtrasChestRef.RemoveAllItems(selfRef, True, True) EndIf PoisonedWeaponAlias.SetWeapon(Item) RemoveInventoryEventFilter(Item) ((Self as ReferenceAlias) as B2CraPlayerAliasPotionCraft).Reset() EndEvent EndState Auto State Done Event OnItemRemoved(Form Item, int NA, ObjectReference ItemRef, ObjectReference akDestContainer) EndEvent EndState Function SetUp() AddInventoryEventFilter(PotionAlias.GetReference().GetBaseObject()) GoToState("") EndFunction The Potion Alias Scriptname B2CameKrosisPotion extends activemagiceffect Int Property AcquireItemObj Auto Int Property PotionLostObj Auto Int Property KillTargetObj Auto Int Property FailedToKillTargetObj Auto Quest Property QST Auto ReferenceAlias Property PoisonedAlias Auto B2CraPoisonedWeapon Property PoisonedWeaponAlias Auto Event OnEffectStart(Actor Target, Actor Caster) PoisonedWeaponAlias.TargetVar = True If Target == PoisonedAlias.GetReference() as Actor PoisonedWeaponAlias.ClearWeapon() ActorBase AB = Target.GetActorBase() If AB.IsInvulnerable() AB.SetInvulnerable(False) EndIf QST.SetObjectiveDisplayed(KillTargetObj) Utility.Wait(30.0) Int i = 150 While(i > 0) && !Target.IsDead() If (i == 150) Debug.Notification("Potion Wears Off In") EndIf Debug.Notification(i + " Seconds") i = i - 30 Utility.Wait(30.0) EndWhile Else QST.SetObjectiveFailed(AcquireItemObj) EndGame(PotionLostObj) EndIf PoisonedWeaponAlias.TargetVar = False EndEvent Event OnEffectFinish(Actor Target, Actor Caster) If !Target || Target.IsDead() Return Else ActorBase AB = Target.GetActorBase() If AB.IsInvulnerable()==False AB.SetInvulnerable() EndIf QST.SetObjectiveFailed(AcquireItemObj) QST.SetObjectiveFailed(KillTargetObj) EndGame(FailedToKillTargetObj) EndIf EndEvent Function EndGame(Int Obj) QST.SetObjectiveDisplayed(Obj) Utility.Wait(5.0) Game.GetPlayer().Kill() EndFunction The Weapon Alias Scriptname B2CraPoisonedWeapon extends ReferenceAlias B2CquWildmanQuestScript Property B2CquWildman Auto Keyword Property WeapTypeBow Auto Int Property AcquireItemObj Auto Int Property PotionLostObj Auto Bool Property TargetVar Auto Hidden Event OnEquipped(Actor akActor) RegisterForAnimationEvent(akActor, "arrowRelease") EndEvent Event OnUnequipped(Actor akActor) UnRegisterForAnimationEvent(akActor, "arrowRelease") EndEvent Event OnAnimationEvent(ObjectReference akSource, string asEventName) If asEventName == "arrowRelease" Else Return EndIf If akSource == Game.GetPlayer() Else Return EndIf Utility.Wait(4) If TargetVar UnRegisterForAnimationEvent(akSource, "arrowRelease") Clear() Return EndIf Quest QST = GetOwningQuest() QST.SetObjectiveFailed(AcquireItemObj) QST.SetObjectiveDisplayed(PotionLostObj) Utility.Wait(5) (akSource As Actor).Kill() EndEvent Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) ObjectReference PlayerRef = Game.GetPlayer() If AkNewContainer Else PlayerRef.AddItem(GetReference(), AbSilent = true) B2CquWildman.B2CmsOblivionChestNoDrop.Show() Return EndIf If AkNewContainer == PlayerRef Return Else AkNewContainer.RemoveItem(GetReference(), 1 , False, PlayerRef) B2CquWildman.B2CmsOblivionChestNoDrop.Show() EndIf EndEvent Function SetWeapon(Form Poisoned) If Poisoned.HasKeyword(WeapTypeBow) RegisterForAnimationEvent(Game.GetPlayer(), "arrowRelease") Else GoToState("NoBow") EndIf EndFunction Function ClearWeapon() If GetState() == "NoBow" Clear() EndIf EndFunction State NoBow Event OnEquipped(Actor akActor) EndEvent Event OnUnequipped(Actor akActor) EndEvent EndState If you had two scripts on one alias and both had add and remove item events. Would an inventory event filter you put on one script also effect the events on the other script? I have read some conflicting information about this. However the answer is Yes, It will effect other on item add or remove events on that reference alias. Edited February 3, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Recommended Posts