Jump to content

Photo

Issues while scripting for puzzles, need assist

papyrus script help

  • Please log in to reply
25 replies to this topic

#11
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Yup. That's partially why this has been so confusing, all the activation handoff code has been present since day 1, but behaves in a (seems to me) inconsistent manner.

 

Let's focus back on the bear puzzle, since it was changed the most and is now completely nonfunctional, but *looks* like it should work fine.

 

In the bear; properties DoorController == EFTH_PZ1_DoorController (XMarker), LightController == EFTH_PZ1_LightController (XMarker). No other linkages present for references.

Scriptname EFTH_Puzzle01Control extends ObjectReference

ObjectReference property DoorController auto
ObjectReference property LightController auto


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	if (aiItemCount > 0)
		DoorController.activate(game.getplayer())
		debug.trace("DoorController called  active by" + self)
		LightController.activate(game.getplayer())
		debug.trace("LightController called active by" + self)
	endIf
endEvent

in EFTH_PZ1_DoorController; properties ControlledDoor == EFTH_PZ1_ExitDoor (BldWoodPDoor01), no other linkages present

Scriptname EFTH_DoorControlActivator extends ObjectReference

objectReference property ControlledDoor auto

Event onActivate(ObjectReference akActionRef)
	debug.trace("DoorController recieved activation from " +akActionRef)
	;ControlledDoor.Activate(game.getplayer())
	if (ControlledDoor.isLocked())
		ControlledDoor.unlock()
		ControlledDoor.setOpen()
	endIf
endEvent
	

Note that I'm no longer trying activate or using a script in the door object, I'm just checking for locked condition before unlock/open.

 

in EFTH_PZ1_LightController; properties IndicatorLight == EmergencyLightAnim01 0700645C, no other linkages for ref

Scriptname EFTH_IndicatorLightScript extends ObjectReference

ObjectReference property IndicatorLight 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")
	endIf
endEvent

All that was changed here is an attempt to avoid changes to the light state (set green anim once and leave it alone) with possible errant activations.

 

Change in behavior? Nothing happens at all. Door's locked inaccessible and stays that way, no matter how I stuff the bear. Light never plays anim (turns green).

 

So... not passing activate()? If I use the activate parent link, everything fires when I open/close the bear's inventory unless I use that vanilla doorUnlockOnActivate script in the door itself, and I can't leave the door usable after that.

 

Ignore the other two puzzles until I can get this one working, I have a feeling they'll fall in line once the issue's fixed with this one.



#12
ThoraldGM

ThoraldGM

    Old hand

  • Premium Member
  • 511 posts

Ha. I just noticed you are missing the required inventory event filter.

 

From wiki: "Event received when an item is inserted into this object's container. Only arrives if it matches an inventory filter in place on the script receiving the event."

AddInventoryEventFilter(NONE)

A filter for NONE seems counter intuitive, but that's what I'm using in my own project. (See line 127: https://pastebin.com/S2NMkt3z)

 

You would place it in the bear's OnInit, which is why the initial domino is not falling and activating everything else.



#13
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Alright, so here's where we are;

Scriptname EFTH_Puzzle01Control extends ObjectReference

ObjectReference property DoorController auto
ObjectReference property LightController auto
Keyword property AllowedItem auto

Event onInit()
	AddInventoryEventFilter(AllowedItem)
endEvent

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
	if (aiItemCount > 0)
		DoorController.activate(game.getplayer())
		LightController.activate(game.getplayer())
	endIf
endEvent

Going to set AllowedItem to KYWD ObjectTypeFood, just to finish out the desired functionality.

 

Too bad I can't actually test this out until this evening...



#14
ThoraldGM

ThoraldGM

    Old hand

  • Premium Member
  • 511 posts

Checking that item is food is even better. I like your style. Looking forward to doing the everything works Snoopy Dance.



#15
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

On the picture cycler (seems a better name for it), I didn't realize until just now I'd forgotten to add the cycle script to the picture with the button. Come up with something a little different though, think this will work as planned?

Scriptname EFTH_PictureCycleReset extends ObjectReference

Event OnDestructionStageChanged(int aiOldStage, int aiCurrentStage)
	if (aiCurrentStage > 4)
		self.reset()
	endIf
endEvent

Remember, all the button does is damage the picture object by 25 points... I'm changing up the stages so it starts at 1 with 100% of 99 points and steps up each stage at a 25% step.

 

Stage - post-click HP - stage percentage - enacted percentage

1  -  99  - 100% -  100%

2  -  74  -  75%  -  74.7%

3  -  49  -  50%  -  49.5%

4  -  24  -  25%  -  24.2%

5  -  00  -    0%  -  0%   (since I'm checking for stage > 4, immediately on reaching 5 the object should reset)



#16
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Checking that item is food is even better. I like your style. Looking forward to doing the everything works Snoopy Dance.

 

Well, you've got a big sign in front of you that effectively says 'Feed The Bears!', player better realize that means food :smile:

 

Attached File  Puzzle1_ck2.JPG   191.92KB   0 downloads

 

p.s. the walls have changed since I took that screenshot, turns out there's an entire series of 'concbrick' series of building parts that have no collision mesh on them whatsoever. What a surprise to playtest, back up to get a good screenshot framed (which I never got), and back directly through a wall into the void... swapped everything for plain brick, which is sad because these walls looked good. Suppose I could co-opt the texture but the brick wall fits the story a bit better anyways.



#17
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

w00t!

Attached File  bearpuzzleworks.jpg   237.2KB   0 downloads

 

The bear puzzle now works as intended.

 

That leaves the remaining problems of:

 

1 - assembling ten bowling pin trigger volumes in an array and figuring out how to get *them* to activate remote scripts properly, or rewire the whole thing to avoid that issue, and...

 

2 - figuring out how to properly reset the cycling pictures, as the reset() command doesn't seem to do anything at all.

 

The cycling pictures are going to pose a problem later too, as it seems there's a maximum of 8 damage states available. That's fine for the testing, it's fine for the color pictures (aqua, blue, green, violet, red, yellow, white == 7, plus 1 for the start state). But the numeric pictures will need 10 states and alphabetic would need 27.

 

If there were another easy way to swap object references, or material swaps, or even NIFs like the damage cycle does...



#18
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Ok, next issue to tackle. What I'm about to post *has* been modified and not tested yet. This is for the cycling pictures...

 

This is an unnamed reference of EFTH_PictureFrameMSTT_TEST02. It's base object is set up with destruction data as follows;
Attached File  testpicture.jpg   58.76KB   0 downloads

 

Attached to the reference is this script:

Scriptname EFTH_PictureCycleReset extends ObjectReference

Event OnDestructionStageChanged(int aiOldStage, int aiCurrentStage)
	int CurrentStage = self.getCurrentDestructionStage()	
	if (CurrentStage > 4)
		self.clearDestruction()
	endIf
endEvent

Previously I'd tried both clearDestruction and self.reset() with no change in behavior.

 

Next to the frame, is unnamed ref of base object EFTH_RedButton01. This ref has two scripts attached;

1 - Default1StateActivator (vanilla, for the button press anim)

2 - EFTH_PictureButtonTest; property TargetedItem is set to the TEST2 picture frame ref above.

Scriptname EFTH_PictureButtonTest extends ObjectReference

Objectreference property TargetedItem auto

Event OnActivate(ObjectReference akActionRef)
	TargetedItem.DamageObject(25.0)
EndEvent

What's supposed to happen here, is that the picture starts with 99 hit points and basically just sits there. Pressing the button once damages the picture by 25 points, resulting in 74HP, which is 74.7% and thus below the 75% threshold for setting destruction stage 2. When stage 2 is set, the NIF is swapped to the second prewar picture frame. Another press takes 25HP, same deal with HP and percentages, stage increments, NIF changes.

 

To the player, this appears to change the picture with every press of the button.

 

This obviously can't go on forever; stage 4 is the 'last' stage and stage 5 is hit when HP reaches 0, and swaps to the same NIF used in the starting stage. When the script on the picture detects the stage changing, it's supposed to check for stage greater than 4, and if so, clear the destruction. It's not clear from documentation what this actually means, but I can tell you that so far, none of my attempts have actually reset the picture... it gets to the last stage and stops changing. The above code has not been tested yet and *may* function... testing will need to be done, but there are overarching questions.

 

QUESTION:

Does anyone out there know what aspects of the MSTT's destruction data are actually 'cleared up' by clearDestruction()? Does it reset JUST the stage and leave the hit points, or does it set everything back to it's original condition?



#19
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Good news!

The setup as described above works perfectly, as intended. No issues there.

 

Now it's down to figuring out the bowling pin puzzle, and actually making the real picture cycling 'machines'.

 

I do still need to know if there's a better swapping solution than the destruction stages (since limited to 8), or simply placing single picture objects overlapping and enabling only one at a time. That seems ripe for a performance hit...



#20
mfree80286

mfree80286

    Fan

  • Premium Member
  • 421 posts

Here's the end result for the picture cycler scripts. They ended up so simple.... changed up the math a little bit since I'm watching the stage and not the percentage, percentage is now in decrements of 10 and the last stage does not go to zero; using a starter HP of 99 and reducing by 10 still puts every click within the next destruction stage's percentage range.

 

This was the original test cycler (moving through 4 vanilla painting NIFs)

Attached File  test_cycle.jpg   35.8KB   0 downloads

 

And this is the end product color cycler (start/end on white, moves through 6 colors)
Attached File  color_cycle.jpg   89.14KB   0 downloads

 

Because of the need for a start and end (reset) stage, 7 is the limit for different NIF aspects. That kills this method for alphanumerics, but it's absolutely elegant for any MSTT that needs no more than 7 swaps. And the NIFs are not limited to those taking the same position, it's probably going to center the new NIF on the same reference coordinates as last and it should center on the NIF's center point.... move the center point, move the NIF. You could produce with this an animated dial with up to 7 positions, shift an object around on a table up to 7 places...

 

Anyhow, lots of possibilities. But I still need to figure out how to get the same effect with 10 and 26 swaps. Started to think of a hybridized model where there are two MSTTs that swap using the enable/disable mechanism; instead of resetting on the last stage, self.disable() and swap.enable() and start counting stages on the swap instead. Doing that with 2 MSTTs would cover numerals, doing it with 4 would cover the alphabet (26 chars, 28 slots).

 

Also need to make some icon based cycling NIFS, but I don't know what kind yet. Could also make frameless patterns that roll or change to make an image when all are correct, a sort of jigsaw puzzle. Also need to write a detection script and make sure I don't run into the activation snafu again.

 

Oh, and the bowling pin puzzle. One trigger volume is one thing, wrangling ten is something else.







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

Page loaded in: 0.818 seconds