Jump to content

[LE] Will this script work as intended?


Masterofnet

Recommended Posts

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 by Masterofnet
Link to comment
Share on other sites

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

 

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 properties

Can I remove the forms this way? Yes

Could I have filled it in the script properties and still removed the forms? With a form list you can not. Yes

Is 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 by Masterofnet
Link to comment
Share on other sites

  • 3 weeks later...

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 by Masterofnet
Link to comment
Share on other sites

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
EndEvent

BTW - I attempted to set the player invulnerable and it would not work. I have never tried before. Has anyone else attempted that?

Edited by Masterofnet
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...