Jump to content

This script drives me crazy and nuts - HEEELP!


Pellape

Recommended Posts

Player.PlaceAtMe BottleRef 1

Ah, I wish there would be a workaround for occasions where PlaceAtMe is required.

 

PlaceAtMe creates a copy of the base item that is saved into the "BottleRef" reference variable.

This copy gets permanently saved into the savegame.

https://cs.elderscrolls.com/index.php?title=PlaceAtMe#Warning:_Repeated_Use_Causes_Save-Game_Bloat

It's similar to "Drop Torch OBSE", where you can drop lit torches. It either uses PlaceAtMe. For each torch dropped. XD

 

For Nehrim, I've updated the mod by giving the placed torches a reference, and use

https://cs.elderscrolls.com/index.php?title=DeleteReference

when the player activates the dropped torch.

In that case I rather use "AddItem" to put a proper torch into the player's inventory and disable the torch the player klicked on and set them up for deletion. :smile:

 

Yet, if your shelf isn't used excessively it may not bloat the savegame drastically with these PlaceAtMe bottles. :wink:

Link to comment
Share on other sites

Mr JustChill: No matter how you turn around, you still have your behind at the back.

 

The collision will not follow if I disable the object, move it and then enable it. I have tried that with other objects. It does not work

Link to comment
Share on other sites

It is 46 bottles that my companions and staff will drink, so then there will be no BLOAT left to delete... ;) Well some BLOATS are NULL references, so then it might still be around.

 

It is odd that all stuff Maskar adds to the game with all his scripts, do not cause BLOAT... I can just check my save game later with WB and see if there is any and last time I did that, I had 2 NULL references, thats all.

Link to comment
Share on other sites

I take a break now. I do not get wiser than this. The line 176, line 8 in State = 2 section, reports an error. I also deleted some initiation code or rather made it more optimal.

	If ( State == 2 )
		If ( TurnZ < 5 )
			If ( TurnX < 6 )

				Let BottleIndex += 1
				;Scribe "BottleNumber = %0.0f" BottleIndex

				Let BottleExist := BottleExistArr[BottleIndex]  ;  <---------------------------------------

The message from console:

Error in script 7305ee4f
Operator := failed to evaluate to a valid result
    File: hobbitHome.esp Offset: 0x0579 Command: Let
Error in script 7305ee4f

The complete latest version of the main script

scn PekFillRackWithBottles02SCR


array_var BottleArr

array_var BottlePosX
array_var BottlePosY
array_var BottlePosZ

array_var BottleAngX
array_var BottleAngY
array_var BottleAngZ

array_var BottleExistArr

Ref BottleRef
Ref BottleRef2
Ref StoredBottleRef
Ref BottleBaseRef
Ref EmptyRef
Ref BeastRef
Ref HandleRef

Float xPos
Float yPos
Float zPos

Float xAngle
Float yAngle
Float zAngle

Float StartX
Float StartY
Float StartZ

;Float RackPosAng

Short Button
Short TurnX
Short TurnZ
;Short Turn
Short BottlesAmmount
Short State
Short Rack
Short DoOnce
Short BottleIndex
Short BottleExist
Short UpdateArrays

Short BottleType
	; Beer 		1
	; Wine01 	2
	; Wine02 	3
	; Milk		4

Begin OnActivate

	Set State to -1
 
End


;;;;;;;;;;;;;;;;;;;;;;;;;;;


Begin GameMode

	If ( State == 0 )
		Return
	EndIf
	
	If ( DoOnce == 0 )
	
		let BottleArr := ar_Construct Array

		let BottlePosX := ar_Construct Array
		let BottlePosY := ar_Construct Array
		let BottlePosZ := ar_Construct Array

		let BottleAngX := ar_Construct Array
		let BottleAngY := ar_Construct Array
		let BottleAngZ := ar_Construct Array
		
		Let BottleExistArr := ar_Construct Array

		Set EmptyRef to 0
		
		
		Set BottleIndex to 0
		
		While ( BottleIndex < 46 )

			let BottleArr[BottleIndex] := 666

			let BottlePosX[BottleIndex] := 0
			let BottlePosY[BottleIndex] := 0
			let BottlePosZ[BottleIndex] := 0

			let BottleAngX[BottleIndex] := 0
			let BottleAngY[BottleIndex] := 0
			let BottleAngZ[BottleIndex] := 0
			
			let BottleExistArr[BottleIndex] := 0
			
			Let BottleIndex += 1
		
		Loop

		let BottleArr[0] := 0

		MessageBoxEX "Make sure the 2 bottle racks are empty this first time. Do you want to fill them with Bottles?|No|Yes|Fix positions"
		Set State to 30
		Set UpdateArrays to 1
		
		Set DoOnce to 1
		
	ElseIf ( State == -1 )
		MessageBoxEX "Do you want to fill the rack with Bottles?|No|Yes|Fix positions"
		Set State to 30
		Set UpdateArrays to 1
	EndIf
	
	;Set BottleIndex to 1
	
	If ( State == 20 )
		Set Button to GetButtonPressed
		
		If ( Button == 0 )
			Set State to 0
			Return
		ElseIf ( Button == 1 )
			Set State to 1
			Set Button to -1
		ElseIf ( Button == 2 )
			Set State to 30
			Set Button to -1
		EndIf
		
	EndIf
	
	If ( State == 1 )
		Set EmptyRef to 0
		Set BottleType to 0
		Set BeastRef to 666

		Let BottlesAmmount := DrinksCabinet01Ref.GetNumItems
	
		If ( BottlesAmmount == 0 )
			MessageBoxEX "Fill up the Upper Cabinet to the right of the rack with bottles"
			Set State to 0
			Return
		EndIf

		; Filling the upper Rack
		Set Rack to 1
		
		; x steps 10.85
		; z steps 13,37
		Set StartX to PekBottleRackRef.Getpos x - 32.52
		Set StartY to PekBottleRackRef.Getpos y - 3.1
		Set StartZ to PekBottleRackRef.Getpos z + 31.17
				
		Set TurnZ to 1
		Set TurnX to 1

		Set State to 2
	EndIf	
	
	If ( State == 2 )
		If ( TurnZ < 5 )
			If ( TurnX < 6 )

				Let BottleIndex += 1
				;Scribe "BottleNumber = %0.0f" BottleIndex

				Let BottleExist := BottleExistArr[BottleIndex]
				
				If ( BottleExist == 0 )
					let BottleArr[BottleIndex] := EmptyRef

					let BottlePosX[BottleIndex] := 0
					let BottlePosY[BottleIndex] := 0
					let BottlePosZ[BottleIndex] := 0

					let BottleAngX[BottleIndex] := 0
					let BottleAngY[BottleIndex] := 0
					let BottleAngZ[BottleIndex] := 0
				EndIf

				Let StoredBottleRef := BottleArr[BottleIndex]


				If eval ( StoredBottleRef == BeastRef )
				ElseIf eval ( StoredBottleRef != EmptyRef )
					Let TurnX += 1
					Return
				EndIf
				
				Call PekCheckBottleTypesFUN
				
				
				;Beer and Mead bottles
				Set xPos to StartX + ( 10.85 * TurnX )
				Set yPos to StartY
				Set zPos to StartZ - ( 13.37 * TurnZ )
				
				Set xAngle to -92.5
				Set yAngle to 0
				Set zAngle to 135
				
				If ( BottleType == 2 )
					Set zPos to zPos + 1
					
					Set xAngle to -90
					Set zAngle to 165
				ElseIf ( BottleType == 3 )
					Set zPos to zPos + 1
					
					Set xAngle to -90
				ElseIf ( BottleType == 4 )
					Set xPos to xPos + 0.5
					Set yPos to yPos + 2
					Set zPos to zPos + 1
					
					Set xAngle to -90
				EndIf

				Set TurnX to TurnX + 1

				
				If eval ( BottleRef != EmptyRef )
					Player.PlaceAtMe BottleRef 1
					DrinksCabinet01Ref.RemoveItemNS BottleRef 1

					Set State to 3
					Return
				EndIf	

		
				
			Else
				Set TurnX to 1
				Let TurnZ += 1
			EndIf
		Else 
			Set State to 11
			Set Rack to 2
		EndIf
	EndIf
	
	If ( State == 3 )
		BottleRef.disable
		Set State to 4
		Return
	EndIf

	If ( State == 4 )
		BottleRef.enable
		Set State to 5
		Return
	EndIf	

	If ( State == 5 )

		;Printc "Bottle == %i %n", BottleRef, BottleRef
	
		Let BottleRef2 := GetFirstRef 40 4
		While ( BottleRef2 )
			Let BottleBaseRef := BottleRef2.GetBaseObject
			If eval ( BottleBaseRef == BottleRef )
				Set BottleRef to BottleRef2
				Break
			EndIf
			
			Let BottleRef2 := GetNextRef
		loop
					
		If eval ( BottleRef != PekBottleRackRef || BottleRef == EmptyRef )
			BottleRef.SetPos x xPos
			BottleRef.SetPos y yPos
			BottleRef.SetPos z zPos
			
			BottleRef.SetAngle x xAngle
			BottleRef.SetAngle y yAngle
			BottleRef.SetAngle z zAngle
			
			PrintC "BottleIndex = %g" BottleIndex
			
			let BottleArr[BottleIndex] := BottleRef

			let BottlePosX[BottleIndex] := xPos
			let BottlePosY[BottleIndex] := yPos
			let BottlePosZ[BottleIndex] := zPos

			let BottleAngX[BottleIndex] := xAngle
			let BottleAngY[BottleIndex] := yAngle
			let BottleAngZ[BottleIndex] := zAngle
			
			let BottleExistArr[BottleIndex] := 1			
		EndIf
		
		Set State to 6
		Return
	EndIf
	
	If ( State == 6 )
		BottleRef.disable

		Set State to 7
		Return
	EndIf

	If ( State == 7 )
		BottleRef.Enable
		
		If ( Rack == 1 )
			Set State to 2
		ElseIf ( Rack == 2 )
			Set State to 12
		EndIf
		
		Return
	EndIf
	
	;Filling the lower Rack

	; x steps 14
	; z steps 13,22
	If ( State == 11 )
	
		Set StartX to PekBottleRackRef.Getpos x - 35.3
		Set StartY to PekBottleRackRef.Getpos y + 8
		Set StartZ to PekBottleRackRef.Getpos z - 35.3
				
		Set TurnZ to 1
		Set TurnX to 1
		
		Set State to 12
	EndIf
	
	If ( State == 12 )
		
		If ( TurnZ < 5 )
			If ( TurnX < 5 )

				Let BottleIndex += 1
				;Scribe "BottleNumber = %0.0f" BottleIndex

				Let BottleExist := BottleExistArr[BottleIndex]
				
				If ( BottleExist == 0 )
					let BottleArr[BottleIndex] := EmptyRef

					let BottlePosX[BottleIndex] := 0
					let BottlePosY[BottleIndex] := 0
					let BottlePosZ[BottleIndex] := 0

					let BottleAngX[BottleIndex] := 0
					let BottleAngY[BottleIndex] := 0
					let BottleAngZ[BottleIndex] := 0
				EndIf

				Let StoredBottleRef := BottleArr[BottleIndex]

				If eval ( StoredBottleRef == BeastRef )
				ElseIf eval ( StoredBottleRef != EmptyRef )
					Let TurnX += 1
					Return
				EndIf

				Call PekCheckBottleTypesFUN

				;Beer and Mead bottles
				Set xPos to StartX + ( 14 * TurnX )
				Set yPos to StartY - 15
				Set zPos to StartZ - ( 13.22 * TurnZ )
				
				Set xAngle to -90
				Set yAngle to 0
				Set zAngle to 135
				
				If ( BottleType == 2 )
					Set zPos to zPos + 1
					
					Set zAngle to 165
				ElseIf ( BottleType == 3 )
					Set zPos to zPos + 1
				ElseIf ( BottleType == 4 )
					Set xPos to xPos + 0.5
					Set yPos to yPos + 2
					Set zPos to zPos + 1
				EndIf

				Set TurnX to TurnX + 1
				
				If eval ( BottleRef != EmptyRef )
					Player.PlaceAtMe BottleRef 1
					DrinksCabinet01Ref.RemoveItemNS BottleRef 1

					let BottleArr[BottleIndex] := BottleRef

					let BottlePosX[BottleIndex] := xPos
					let BottlePosY[BottleIndex] := yPos
					let BottlePosZ[BottleIndex] := zPos

					let BottleAngX[BottleIndex] := xAngle
					let BottleAngY[BottleIndex] := yAngle
					let BottleAngZ[BottleIndex] := zAngle
					
					let BottleExistArr[BottleIndex] := 1

					Set State to 3
					Return
				EndIf
			Else
				Set TurnX to 1
				Set TurnZ to TurnZ + 1
			EndIf
		Else
			Set State to 0
			Set TurnZ to 1
		EndIf
		

	EndIf
	
	
	
	If ( State == 30 )

		Printc "Initiates positioning"

		Set EmptyRef to 0
		Set BeastRef to 666
		Set HandleRef to GetSelf
		
		Set BottleIndex to 1
		
		While (BottleIndex < 46 )

			Let StoredBottleRef := BottleArr[BottleIndex]
		
			If eval ( StoredBottleRef != EmptyRef || StoredBottleRef != BeastRef )
				Let BottleRef2 := GetFirstRef 40 4
				While ( BottleRef2 )
					If eval ( BottleRef2 == StoredBottleRef && BottleRef2 != EmptyRef)
						let BottleExistArr[BottleIndex] := 1
						Break
					Else 
						let BottleExistArr[BottleIndex] := 0
					EndIf
					
					Let BottleRef2 := GetNextRef
				loop	

				Let BottleExist := BottleExistArr[BottleIndex]
				
				If ( BottleExist == 1 )
					If Eval ( BottleRef2 != HandleRef )
						Let xPos := BottlePosX[BottleIndex]
						Let yPos := BottlePosY[BottleIndex]
						Let zPos := BottlePosZ[BottleIndex]
						
						Let xAngle := BottleAngX[BottleIndex]
						Let yAngle := BottleAngY[BottleIndex]
						Let zAngle := BottleAngZ[BottleIndex]

						BottleRef2.SetPos x xPos
						BottleRef2.SetPos y yPos
						BottleRef2.SetPos z zPos
						
						BottleRef2.SetAngle x xAngle
						BottleRef2.SetAngle y yAngle
						BottleRef2.SetAngle z zAngle
					EndIf
				EndIf
			EndIf
			
			Printc "BottleIndex = %g - %i %n - Exist? %g" BottleIndex BottleRef2 BottleRef2 BottleExist
			Let BottleIndex += 1
		Loop
		
		If ( UpdateArrays == 1 )
			Set State to 20
			Set UpdateArrays to 0
		Else
			Set State to 0
		EndIf
	EndIf

End

This forum sux. It doesn't update itself, bloody crap - But it is fun never the less anyway... ;)

Link to comment
Share on other sites

I am not sure if using an item that is created with PlaceAtMe gets cleared.

At least for custom summon spells that use PlaceAtMe, the summons (when spell time over or killed) resulted in a bloat of the savegame as their objects never got cleared out of the game, even if disabled and moved to another cell.

They only get cleared if they are disabled and the cell they are in gets reset (which only happens if the player visits that cell once).

In that case it was recommended to use Initially disabled actors that get enabled and moved to the player when the summon spell is used.

 

 

But used bottles cannot get resurrected and re-enabeld, so similar to the drop torch mod, PlaceAtMe might be the only way to solve this.

 

 

 

I take a break now. I do not get wiser than this. The line 176, line 8 in State = 2 section, reports an error. I also deleted some initiation code or rather made it more optimal.

	If ( State == 2 )
		If ( TurnZ < 5 )
			If ( TurnX < 6 )

				Let BottleIndex += 1
				;Scribe "BottleNumber = %0.0f" BottleIndex

				Let BottleExist := BottleExistArr[BottleIndex]  ;  <---------------------------------------

You raise the array index by 1 before actually using it as index for the array.

So the index var will never be 0 and probably be higher than the amount of entries in the array.

 

 

You may use

While eval(Ar_Size BottleExistArr) > BottleIndex
; Operations...
Let BottleIndex += 1
Loop

to be sure that you won't run outside of the actual array size.

 

Ar_Size returns

-1 if the array is not initialized

0 if the array is empty

and any other positive amount regarding the size. :D

 

 

 

 

 

In addition:

Ah I just realized that you don't run through the array in State 2.

Being a bit unsure about why you raise the array index right upon start in that state then.

Regarding the index value before, this could still turn out to end up as index mismatch anyways. :/

Link to comment
Share on other sites

Raising "BottleIndex" at the end of a "while" it will be taken care of never to exceed the max index. Raising it at the beginning of some conditional block, where no condition checks for how large it already is, can easily go beyond the max. index of the array you're trying to access. You should definitely add in a check there before the array access.

And I wasn't telling to use one kind of increment instead of another. I was telling there was one line in the "State == 12" block which was neither and to me didn't look right:

Let BottleIndex := + 1

It was still inside the first reworked script, but I can't see it anymore inside the last. So it was also fixed along the line.

Link to comment
Share on other sites

Yes, most likely as I lost track about what I have been fixing, as it is small stuff here and there that needs to be fixed. I did write in my WIP that I thought this was gonna be easy but never knew it was gonna be more complex... :D

It is a tiny bottle that will get added to a rack after all. How hard can it be? ;)

Link to comment
Share on other sites

You did ask why I start some code sections with

Let Variable += 1

Well it is because it is 46 array indexes but 45 bottles. I do want to have bottle number 1 as index 1, not index 0 so it is optimal that way. You also see in the initiating of the arrays, that I set index 0 to 0 after the loop now. At line 109.

 

I could make a separate section, starting by setting BottleIndex to 1 which I most likely tried to do really, which ended up else where. Why did I remark that line and not just delete it? Well I got a feeling I was gonna check it out sooner or later... Why did it end up there, as a reminder, Pekka - Do check that line out. What the hell where you thinking? Coding will make you blind after a while as you are here now at this present. If you go back and read code you wrote a week ago, you will end up with an empty mind, if you are unlucky.

 

A way to get a picture of what is going on in a script is to make a flow chart first but it will not prevent mistakes nor misspelling, not tiredness nor un focusing. I have not created any since I wrote that crap about yEd, but I will next time I make the next script, no matter the size.

Edited by Pellape
Link to comment
Share on other sites

  • Recently Browsing   0 members

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