Jump to content

Photo

Issues while scripting for puzzles, need assist

papyrus script help

  • Please log in to reply
25 replies to this topic

#21
mfree80286

mfree80286

    Fan

  • Premium Member
  • 324 posts

Alright, untested new method for the full bowling pin puzzle.

 

1 - the trigger volume. There are two scripts available for a volume now;

Scriptname EFTH_ItemInTriggerPos extends ObjectReference

ObjectReference property PuzzContainer auto
Keyword property PuzzleItemKeyword auto
Keyword property PuzzToken auto

event onTriggerEnter (ObjectReference akTriggerRef)
	if akTriggerRef.HasKeyword(PuzzleItemKeyword)
		PuzzContainer.AddItem(PuzzToken,1,true)
	endIf
endEvent

event onTriggerLeave (ObjectReference akTriggerRef)
	if GetTriggerObjectCount() == 0
		PuzzContainer.RemoveItem(PuzzToken,1,true)
	endIf
endEvent
Scriptname EFTH_ItemInTriggerNeg extends ObjectReference

ObjectReference property PuzzContainer auto
Keyword property PuzzleItemKeyword auto
Keyword property PuzzToken auto

event onTriggerEnter (ObjectReference akTriggerRef)
	if akTriggerRef.HasKeyword(PuzzleItemKeyword)
		PuzzContainer.RemoveItem(PuzzToken,1,true)
	endIf
endEvent

event onTriggerLeave (ObjectReference akTriggerRef)
	if GetTriggerObjectCount() == 0
		PuzzContainer.AddItem(PuzzToken,1,true)
	endIf
endEvent

Basically you have a positive and negative version... both work the same as far as detection goes (only the bowling pin item) but now add or remove a special keyworded puzzle token MISC item from a 'magical' container, when they are in or out of the trigger volume. Pos is for the volumes that 'want' pins, Neg is for the volumes that should be empty.

 

Then, you have the hidden token container, and it's script;

Scriptname EFTH_Puzzle02Container extends ObjectReference

ObjectReference property PuzzController auto
Keyword property AllowedItem auto

Event onInit()
	AddInventoryEventFilter(AllowedItem)
endEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	if (aiItemCount == 10)
		PuzzController.activate(game.getplayer())
	endIf
endEvent

This works like the bear puzzle, except it watches for 10 token items to be present representing that the 10 trigger volumes have all been manipulated correctly. Then it activates the control marker, which has this script, slightly modified from original, as well as the bear-style doorcontroller script.

Scriptname EFTH_IndicatorLightScript extends ObjectReference

ObjectReference property IndicatorLight auto
Sound property RingBell auto
bool ScriptActivated

event onInit()
	ScriptActivated = 0
endEvent

event onActivate(objectReference akActionRef)
	debug.trace("LightController recieved activation from " +akActionRef)
	if (ScriptActivated == 0)
		ScriptActivated = 1
		IndicatorLight.PlayAnimation("Green")
		int instanceID = RingBell.Play(IndicatorLight)
	endIf
endEvent

Major change there is to ring a bell when the light is activated, since this is portable script and further down the line, doors/lights will happen outside the player's sightline.

 

Will see if this all works in a couple hours, but if you see any obvious screwups, commentary is greatly appreciated.



#22
mfree80286

mfree80286

    Fan

  • Premium Member
  • 324 posts

Doesn't work, multiple reasons. Will address later.

 

EDIT: Yup, entire scheme's just far too complex to be workable right now, so I'm going to simplify the whole thing down to having two pins to place in the correct spots, and that's all. Coding later, presently exhausted.



#23
ThoraldGM

ThoraldGM

    Old hand

  • Premium Member
  • 501 posts
Your project has lots of cool features. Don't throw the baby out with the bath water. Replace aiItemCount with GetItemCount() == 10 because adding one token at a time will never be adding 10 tokens at once.

#24
mfree80286

mfree80286

    Fan

  • Premium Member
  • 324 posts

Your project has lots of cool features. Don't throw the baby out with the bath water. Replace aiItemCount with GetItemCount() == 10 because adding one token at a time will never be adding 10 tokens at once.

 

The bigger problem with the 10 volume puzzle is that if you akwardly move a pin through more than one volume it still affects the total, in this case dropping the count and for some reason not raising it.

 

That portion of the code got replaced in testing, this is that script currently;

Scriptname EFTH_Puzzle02Container extends ObjectReference

ObjectReference property PuzzController auto
Keyword property AllowedItem auto

Event onInit()
	AddInventoryEventFilter(AllowedItem)
endEvent

Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
	if (self.getItemCount(AllowedItem) >= 10)
		PuzzController.activate(game.getplayer())
	endIf
endEvent

So, unless I can find another set of functions to pick on and try to get the 10 volume puzzle working, I'm going to cut it to two pins and a simple check for two trigger entries against pin objects.

 

EDIT: Derp. Like removing the ontriggerenter events from the negative volume script, the ontriggerleave parts from the positive volume script, and put a one-shot bool in both....



#25
mfree80286

mfree80286

    Fan

  • Premium Member
  • 324 posts

Eeee!

Attached File  first_bowlingpuzzle_success.jpg   180.99KB   0 downloads

 

First success! It's still being a little weird... I've tried to idiotproof the negative volume scripts by disabling the puzzleitem object when it leaves the trigger volume, but some stay and don't trip their volumes... but others make up by doing so twice. In the end, the 7/10 split was done, the newly complicated positive volume scripts work fine (they init a token, remove it if the pin is taken as it shouldn't be, but added back when it's replaced, but then trips and stops checking)

 

All these new 'tripped' bools are blocks for the script re-running since we're looking for one-shots here. This is why I'm disabling the bowling pin when removed from the negative volumes, can't screw up a trigger script by replacing and re-removing items if they're gone.

Scriptname EFTH_ItemInTriggerNeg extends ObjectReference

ObjectReference property PuzzContainer auto
Keyword property PuzzleItemKeyword auto
Form property PuzzToken auto
Bool VolumeTripped = false

event onTriggerLeave (ObjectReference akTriggerRef)
	if VolumeTripped == 0
		if akTriggerRef.hasKeyword(PuzzleItemKeyword)
			PuzzContainer.AddItem(PuzzToken,1,true)
			VolumeTripped = 1
			akTriggerRef.disable()
		endIf
	endIf
endEvent

Positive volume will check for removal, since it's a valid puzzle status, but starts off 'solved', removes the token if you take the pin, and replaces the token in the container when you put the pin back, then stops checking status

Scriptname EFTH_ItemInTriggerPos extends ObjectReference

ObjectReference property PuzzContainer auto
Keyword property PuzzleItemKeyword auto
Form property PuzzToken auto
Bool VolumeTrippedOut = false
Bool VolumeTripped = false

event onInit()
	PuzzContainer.addItem(PuzzToken,1,true)
endEvent

event onTriggerLeave (ObjectReference akTriggerRef)
	if VolumeTripped == 0
		if akTriggerRef.hasKeyword(PuzzleItemKeyword)
			if GetTriggerObjectCount() == 0
				PuzzContainer.RemoveItem(PuzzToken,1)
				VolumeTrippedOut = 1
			endIf
		endIf
	endIf
endEvent

event onTriggerEnter (ObjectReference akTriggerRef)
	if VolumeTripped == 0
		if VolumeTrippedOut == 1
			if akTriggerRef.HasKeyword(PuzzleItemKeyword)
				if GetTriggerObjectCount() == 1
					PuzzContainer.AddItem(PuzzToken,1,true)
					VolumeTripped = 1
				endIf
			endIf
		endIf
	endIf
endEvent



The container got redundancy, basically. I was unsure if token additions or removals were being tracked through ALL conditions, so I'm just checking separately on all. It's a simple item count check that trips the puzzle as solved when matched, so it doesn't matter which method catches it, it only matters that it's caught.

Scriptname EFTH_Puzzle02Container extends ObjectReference

ObjectReference property PuzzController auto
Keyword property AllowedItem auto
Bool CodeTripped = false

Event onInit()
	AddInventoryEventFilter(AllowedItem)
endEvent

Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
	if CodeTripped == 0
		if (self.getItemCount(AllowedItem) >= 10)
			PuzzController.activate(game.getplayer())
			CodeTripped = 1
		endIf
	endIf
endEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) 
	if CodeTripped == 0
		if (self.getItemCount(AllowedItem) >= 10)
			PuzzController.activate(game.getplayer())
			CodeTripped = 1
		endIf
	endIf
endEvent

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
 	if CodeTripped == 0
		if (self.getItemCount(AllowedItem) >= 10)
			PuzzController.activate(game.getplayer())
			CodeTripped = 1
		endIf
	endIf
endEvent

No solid clue why some neg volumes didn't detect their pins being removed... I may have to change the negative volume script to check for it's specific placed object reference rather than the puzzleitemkeyword...



#26
mfree80286

mfree80286

    Fan

  • Premium Member
  • 324 posts

Final set of changes and I think it's done. Probably.

 

Changed the MISC bowling pins to new MSTT bowling pins with same keyword attached. Why?

Because you could take the MISC ones and that doesn't trip the trigger volume on removal.

 

With the moveable static bowling pins, you can't screw up... you get the 'neg vol' pins out of their trigger volumes and they disappear; and as long as the remaining two pins are in the 'pos vol' trigger boxes, you'll have 10 tokens in the container and the last change to that number will activate the puzzle controller and light/bell/unlock door.







Also tagged with one or more of these keywords: papyrus script help

Page loaded in: 0.722 seconds