Jump to content

mfree80286

Premium Member
  • Posts

    84
  • Joined

  • Last visited

Nexus Mods Profile

About mfree80286

mfree80286's Achievements

Enthusiast

Enthusiast (6/14)

0

Reputation

  1. Have you considered using is3DLoaded and a boolean together in a little function that uses a while loop to wait until the object returns true, then moving? Could TryToEnable the landing point reference instead... Or, add properties to the script that implicitly declare those landing points. You don't have to do anything with them, you just have to have a property with the objectreference in it. https://www.creationkit.com/index.php?title=Persistence_(Papyrus)
  2. 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.
  3. Eeee! 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...
  4. 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....
  5. 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.
  6. 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.
  7. 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) And this is the end product color cycler (start/end on white, moves through 6 colors) 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.
  8. 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...
  9. 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 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?
  10. w00t! 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...
  11. Well, you've got a big sign in front of you that effectively says 'Feed The Bears!', player better realize that means food :smile: 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.
  12. 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)
  13. 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. 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.
  15. This is the script in the trigger volume (it's not quite there with onTriggerLeave but this was made to demonstrate first) Scriptname EFTH_ItemInTrigger01 extends ObjectReference ObjectReference property PuzzControllerAct auto Keyword property PuzzleItemKeyword auto event onTriggerEnter (ObjectReference akTriggerRef) if akTriggerRef.HasKeyword(PuzzleItemKeyword) PuzzControllerAct.activate(akTriggerRef) endIf endEvent event onTriggerLeave (ObjectReference akTriggerRef) if GetTriggerObjectCount() == 0 PuzzControllerAct.activate(akTriggerRef) endIf endEvent PuzzControllerAct is a reference to the control marker. This apparently does not properly pass activate()...
×
×
  • Create New...