Masterofnet Posted January 28, 2017 Share Posted January 28, 2017 (edited) I am not all that familiar with Arrays, I almost only use form lists. This script compiles. A couple of questions. 1. I could not find a way to create the array inside a function, which you have to do and define it outside. So I used an array property as you can see. Can I fill it this way? Can I remove the forms this way? Could I have filled it in the script properties and still removed the forms? With a form list you can not. Is there a way to create the array within the script and define it outside the function? Will this thing actually work? Scriptname B2CraPlayerAlias extends ReferenceAlias ReferenceAlias[] Property RefArray Auto ReferenceAlias Property ArrowRef Auto ReferenceAlias Property BowRef Auto ReferenceAlias Property Slab Auto ReferenceAlias Property Blade Auto ReferenceAlias Property Mace Auto ReferenceAlias Property BallBreaker Auto Event OnInit() Bool InitGate If InitGate == False RefArray[0] = ArrowRef RefArray[1] = BowRef RefArray[2] = Slab RefArray[3] = Blade RefArray[4] = Mace RefArray[5] = BallBreaker Int i While i < 6 AddInventoryEventFilter(RefArray[i].GetReference().GetBaseObject()) I += 1 EndWhile InitGate = True EndIf EndEvent Event OnItemAdded(Form Item, int IC, ObjectReference ItemRef, ObjectReference NA) GoToState("Done") ObjectReference SelfRef = GetReference() Int i = 0 While Item != RefArray[i].GetReference().GetBaseObject() i += 1 EndWhile SelfRef.RemoveItem(Item,1,True) SelfRef.AddItem(RefArray[i].GetReference(),1,True) RemoveInventoryEventFilter(RefArray[i].GetReference().GetBaseObject()) RefArray[i] = None ArraySort(RefArray) Int Count = ArrayCount(RefArray) If Count < 1 GoToState("Done") Else GoToState("") EndIf EndEvent State Done Event OnItemAdded(Form Item, int IC, ObjectReference ItemRef, ObjectReference NA) EndEvent EndState bool function ArraySort(ReferenceAlias[] RefArray, Int i = 0) ;-----------\ ;Description \ Author: Chesko ;---------------------------------------------------------------- ;Removes blank elements by shifting all elements down. ;Optionally starts sorting from element i. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; false = No sorting required ; true = Success bool bFirstNoneFound = false int iFirstNonePos = i while i < RefArray.Length if RefArray[i] == none if bFirstNoneFound == false bFirstNoneFound = true iFirstNonePos = i i += 1 else i += 1 endif else if bFirstNoneFound == true ;check to see if it's a couple of blank entries in a row if !(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 += 1 endif else i += 1 endif endif endWhile return false endFunction int function ArrayCount(ReferenceAlias[] RefArray) ;-----------\ ;Description \ Author: Chesko ;---------------------------------------------------------------- ;Counts the number of indices in this array that do not have a "none" type. ;-------------\ ;Return Values \ ;---------------------------------------------------------------- ; int myCount = number of indicies that are not "none" int i = 0 int myCount = 0 while i < RefArray.Length if RefArray[i] != none myCount += 1 i += 1 else i += 1 endif endWhile ;notification("MyCount = " + myCount) return myCount endFunction Edited January 28, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 28, 2017 Share Posted January 28, 2017 Can I fill it this way? Possibly. I want to say yes, but part of me isn't to sure when using the property approach. Can I remove the forms this way? If you are using Chesko's method, yes. Could I have filled it in the script properties and still removed the forms? With a form list you can not. Possibly. Not sure to be honest. Is there a way to create the array within the script and define it outside the function? Create within script, yes. Define outside of function, no. Example: ;outside of any function - local non-property array String[] KMOBehave ;inside function - array definition KMOBehave = new string[2] KMOBehave[0] = "$Transfer and Activate" KMOBehave[1] = "$Transfer only" Will this thing actually work? If it compiles, test it in-game and find out. :tongue: I don't quite get what you are trying to do here. You are applying an inventory event filter which will only trigger with specific items. So when those items get added, you remove the item and re-add the same item while taking it off of the inventory event filter. What exactly is your goal? Link to comment Share on other sites More sharing options...
Masterofnet Posted January 28, 2017 Author Share Posted January 28, 2017 (edited) I don't quite get what you are trying to do here. You are applying an inventory event filter which will only trigger with specific items. So when those items get added, you remove the item and re-add the same item while taking it off of the inventory event filter. What exactly is your goal? The player will receive an item via quest or crafting that does not have an object reference. That item is removed and replaced by the same item in a reference alias for the quest. Update: 1. I could not find a way to create the array inside a function, which you have to do and define it outside. So I used an array property as you can see. Can I fill it this way? I don't know I am going to fill the properties of the array in script propertiesCan I remove the forms this way? YesCould I have filled it in the script properties and still removed the forms? With a form list you can not. YesIs there a way to create the array within the script and define it outside the function? Not that I have been able to find. Most likely, No. Will this thing actually work? Yes it does. I am still open to any feedback or ideas on how to better implement the script. And thanks to Chesko The Snowman. Good work on the functions Here is the final fully Tested Version of the script. Scriptname B2CPlayerAlias extends ReferenceAlias ReferenceAlias[] Property RefArray Auto Function SetFilter() Int i While i < 6 AddInventoryEventFilter(RefArray[i].GetReference().GetBaseObject()) I += 1 EndWhile GoToState("") EndFunction Event OnItemAdded(Form Item, int IC, ObjectReference ItemRef, ObjectReference NU) GoToState("Done") Int Count = ArrayCount(RefArray) If Count < 1 Return EndIf Int i = 0 While Item != RefArray[i].GetReference().GetBaseObject() && i < Count i += 1 EndWhile Form ArrayRef = RefArray[i].GetReference().GetBaseObject() If Item == ArrayRef ObjectReference SelfRef = GetReference() RemoveInventoryEventFilter(ArrayRef) SelfRef.RemoveItem(Item,1,True) SelfRef.AddItem(RefArray[i].GetReference(),1,True) RefArray[i] = none EndIf ArraySort(RefArray) GoToState("") EndEvent Auto State Done Event OnItemAdded(Form Item, int aiItemCount, ObjectReference ItemRef, ObjectReference NU) EndEvent EndState bool function ArraySort(ReferenceAlias[] RefArray, Int i = 0) ;Author: Chesko bool bFirstNoneFound = false int IFirstNonePos = i while i < RefArray.Length If RefArray[i] == none If bFirstNoneFound == false bFirstNoneFound = true IFirstNonePos = i i += 1 Else i += 1 EndIf Else If bFirstNoneFound == true ;check to see If it's a couple of blank entries in a row If !(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 += 1 EndIf Else i += 1 EndIf EndIf EndWhile Return false EndFunction int function ArrayCount(ReferenceAlias[] RefArray) ;Author: Chesko int i = 0 int myCount = 0 while i < RefArray.Length If RefArray[i] != none myCount += 1 i += 1 Else i += 1 EndIf EndWhile Return myCount EndFunction Edited January 28, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Masterofnet Posted January 31, 2017 Author Share Posted January 31, 2017 (edited) Solved. Edited January 31, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Masterofnet Posted February 19, 2017 Author Share Posted February 19, 2017 (edited) This script was to be placed on a Magic Effect and essentially prevents the target from losing any health until damage sustained = the "SpellBaseHP" amount. I have a few questions. 1. This was stated about this script below. Is it true? "Heal = HealthCurrent - akTarget.GetActorValue("Health") => healthcurrent being the health you had at the time of casting, if you have healed yourself in the meantime with restoration spells this gives a negative number, restoreactorvalue treats negatives as positivies and therefore would heal again the amount you healed yourself, wrong, and would also heal the shield by substracting a negative number." The script states ( if Heal is > 0 ) if Heal is a negative number the script should not do anything. It should only add health when the Targets health falls below the health amount when the spell what cast. 2. Can anyone think of a better way to gate this? 3. Will this script not prevent the target from losing any health until they have sustained damage = to the SpellBaseHP? Scriptname InconceivableSpell extends activemagiceffect Float Property SpellBaseHP = 100.0 Auto Float Property w = 0.0 Auto MagicEffect Property ME Auto Int i Event OnEffectStart(Actor akTarget, Actor akCaster) Float Heal Float HealthCurrent = akTarget.GetActorValue("Health") While SpellBaseHP > 0.0 && akTarget.HasMagicEffect(ME) Heal = HealthCurrent - akTarget.GetActorValue("Health") If Heal > 0.0 SpellBaseHP = SpellBaseHP - Heal akTarget.RestoreActorValue("Health", Heal) Endif Utility.Wait(w) EndWhile Dispel() EndEvent Edited February 21, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Masterofnet Posted February 21, 2017 Author Share Posted February 21, 2017 (edited) I was able to run some tests on the script and it works perfectly. It is a very bad idea, and I would either fortify health the SpellBaseHP amount or make the actor invulnerable for a short period of time, but this is completely incorrect information. Your correction of my script is an example with several mistakes, as, for example, this logic: Heal = HealthCurrent - akTarget.GetActorValue("Health") => healthcurrent being the health you had at the time of casting, if you have healed yourself in the meantime with restoration spells this gives a negative number, restoreactorvalue treats negatives as positivies and therefore would heal again the amount you healed yourself, wrong, and would also heal the shield by substracting a negative number. Essentially, butchering a viable script and spreading misinformation by defending it. So, Ryyz, use the modactorvalue script of Masterofnet or use my original script depending on what you want to be the end result, both should work for their own slightly different goals as explained and to the best of my knowledge, but don't use his correction of mine, it's wrong and confusing. I also found a better way of gating it. Scriptname InconceivableSpell extends activemagiceffect Float Property SpellBaseHP = 100.0 Auto Event OnEffectStart(Actor akTarget, Actor akCaster) Float Heal Float HealthCurrent = akTarget.GetActorValue("Health") MagicEffect Inc = Self.GetBaseObject() While SpellBaseHP > 0.0 && akTarget.HasMagicEffect(Inc) Heal = HealthCurrent - akTarget.GetActorValue("Health") If Heal > 0.0 SpellBaseHP = SpellBaseHP - Heal akTarget.RestoreActorValue("Health", Heal) Endif EndWhile Dispel() EndEvent This was the original script Scriptname InvincibleSpell extends activemagiceffect Float Property SpellBaseHP = 100.0 Auto String Property ActorValue = "Health" Auto Float Property UpdateSpeed = 0.2 Auto Actor Target Float HealthCurrent Float HealthPercent Float HealthToHeal Float SpellHP Event OnEffectStart(Actor akTarget, Actor akCaster) Target = akTarget SpellHP = SpellBaseHP RegisterForSingleUpdate(UpdateSpeed) EndEvent Event OnUpdate() If (SpellHP > 0.0) HealthPercent = Target.GetAVPercentage(ActorValue) If (HealthPercent < 1.0) HealthCurrent = Target.GetActorValue(ActorValue) HealthToHeal = ((HealthCurrent / HealthPercent) - HealthCurrent) If HealthToHeal > SpellHP HealthToHeal = SpellHP Endif Target.RestoreActorValue(ActorValue, HealthToHeal) SpellHP -= HealthToHeal Endif RegisterForSingleUpdate(UpdateSpeed) Else self.Dispel() Endif EndEventBTW - I attempted to set the player invulnerable and it would not work. I have never tried before. Has anyone else attempted that? Edited February 23, 2017 by Masterofnet Link to comment Share on other sites More sharing options...
Recommended Posts