mfree80286 Posted March 28, 2017 Share Posted March 28, 2017 tl;dr How does one go about restricting a holotape so that it only functions in a single given terminal? -------Instead of diving deep, I'm just going to describe the desired outcome, since there may be an easier way than what I'm starting. There are two locations of teleporter pads, each has two terminals parked side by side.First terminal is the master control, it's just glitz with a text screen of basically 'device ready, fine targeting enabled, targeting control set remote, bla bla)Second terminal is the targeting control. Initially, it contains a message about test mode, prototype this, etc, 'please insert target data holotape'. There are 'B MODE TARGET DATA' holotapes, each has text basically saying it points to the other teleport pad. This was done by duplicating the targeting control terminal object, editing it slightly, and assigning the new terminal object to the holotape. Now, let's consider these teleport pads as 'outside' and 'inside'. The inside pad, "02", already has the targeting holotape pointing to "01" inserted and loaded. The outside pad "01" has no targeting holotape inserted, and instead has a "I'm so dumb" note next to the skeleton of a researcher who's facepalmed himself to death, because target holotape 02 is sitting on the table next to pad 02 and there's no way back inside (right after the bombs fell). You however can 'run the gauntlet', retrieve the tape, insert it, and have a handy shortcut inside for later use. Other teleport pads and/or functionality may be 'induced' later. Hilarity ensues. But there's a hitch. These targeting data holotapes contain the full text of the targeting control terminals... even though I see no reason they couldn't be loaded in any terminal, or the pip-boy. How does one go about restricting a holotape so that it only functions in a single given terminal? There will be other scripted things to worry about (activating the trigger box when the tape's inserted, but making sure coc'ing on to the other pad doesn't drop you on it's trigger box and coc you right back out to the other one and loop/crash) but that's the major question of the moment... I need the holotape pointing to pad 02 to only ever work in target control 01, and the tape pointing to 01 only on targeting control term 02. Don't particularly care if other tapes play on the terminals, but popping 'B MODE TARGET DATA 01' into a subway information terminal and getting the complete targeting control screen would be weird and confusing, since nothing at all would happen. Link to comment Share on other sites More sharing options...
shavkacagarikia Posted March 29, 2017 Share Posted March 29, 2017 I don't think there is a direct way to restrict that. But how about to mimic a holotape? I mean, make a new misc item and use holotape .nif for it. Then add menu on needed terminal which will be seen only if player has that mimicked holotape in inventory. ( maybe it will be better to make two menus with the same names, one is visible if player doesn't have mimicked holotape and when clicked says that you need holotape, and the other does stuff but is only seen if player has mimicked holotape in inventory.) Link to comment Share on other sites More sharing options...
mfree80286 Posted March 29, 2017 Author Share Posted March 29, 2017 Well, the issue seems to me that if there's no way to use a holotape in this manner, then a substitute object falls under the same limitations. I need to rethink how I'm going to handle this... maybe look deeper into how terminals can change their own text options by script, if text replacement can change one line and add a menu option depending if a particular holotape is inserted *or* the right substitute is placed in a dedicated separate container. Or since I have two terminals for each pad, maybe I'm overthinking this and just need to figure how lock the targeting terminal with the specific holotape as a key, and just not have all the extra text on that holotape. Then I can start figuring out the object activation for the trigger and how to safeguard against loops... probably just drop back to activating by switch when everything's right on the terminal, and have it disable itself after both a short wait and on unloading (which should be automatic anyways if the trigger is set to be disabled on load). Link to comment Share on other sites More sharing options...
mfree80286 Posted March 29, 2017 Author Share Posted March 29, 2017 If I use a "holotape" key to unlock the target terminal and attach this to a console button next to them... god I hate scripting. Is this workable, or have I done something untenable? TPTargetTerm is the target terminal (locked, requires key that looks like holotape)TPadTrigger is a trigger box that sits on the pad itself, it'll have the COC script attached to it. I'm just enabling/disabling to make travel possible or not. Disabled by default.TPadReadyIndicator is a ref of 'EmergencyLightAnim01' which has red/yellow/green/off (not sure what names to use with PlayAnimation, the Gambryo anims or the script events?)TPad****Lights are just show lights, on when 'working' I missed some Busy states... not exactly sure why the CK's example has onActivate events for every state but I used them, would love to know why... Scriptname M1V201TeleportButton01 extends ObjectReference ObjectReference property TPTargetTerm auto ObjectReference property TPadTrigger auto ObjectReference property TPadLowLight auto ObjectReference property TPadMidLight auto ObjectReference property TPadReadyIndicator auto EVENT onActivate (objectReference triggerRef) If(TPTargetTerm.isLocked()) GoToState ("TPadOffline") Else GoToState("TPadInactive") EndIf EndEvent State TPadOffline Event onActivate (objectReference triggerRef) Debug.Notification("Device inactive - missing target data") TPadTrigger.disable() TPadLowLight.disable() TPadMidLight.disable() TPadReadyIndicator.PlayAnimation("Red") EndEvent EndState State TPadBusy EndState auto State TPadInactive Event onActivate (objectReference triggerRef) GoToState("TPadBusy") TPadTrigger.disable() TPadLowLight.disable() TPadMidLight.disable() TPadReadyIndicator.PlayAnimation("OFF") gotoState("TPadTransitionUp") EndEvent EndState State TPadTransitionUp Event onActivate (objectReference triggerRef) GoToState("TPadBusy") TPadReadyIndicator.PlayAnimation("Yellow") TPadLowLight.Enable() TPadMidLight.Enable() GoToState("TPadActive") EndEvent EndState State TPadTransitionDown Event onActivate (objectReference triggerRef) TPadReadyIndicator.PlayAnimation("Yellow") TPadTrigger.Disable() TPadLowLight.Disable() TPadMidLight.Disable() GoToState("TPadInactive") EndEvent EndState State TpadActive Event onActivate (objectReference triggerRef) TPadReadyIndicator.PlayAnimation("Green") TPadTrigger.Enable() GoToState("TPadActive") EndEvent EndState What's supposed to happen: 1 - player presses button2 - if player hasn't unlocked the target terminal with the fake 'holotape' key, the pad goes offline with lights out and red light on indicator3 - if player *has* unlocked the target terminal, then the pad enters transition up (lights on, indicator to yellow)4 - when transition up is done, pad goes active... indicator to green, trigger box is enabled5 - the player can now step into the trigger box and transport to the other pad, or wait X seconds (not in code yet) and pad enters transition down (indicator yellow, trigger box disable, lights out)6 - pad goes inactive (lights out, indicator off, trigger disabled) to wait for another input attempt Valid question: Do I need to do anything with the script when the player initiates teleport (coc) to the other pad, or is that automatically managed when the cell unloads (we're in an interior)? EDIT: Hell, ignore the last line in State TPadActive, I was copy-pasting and was just happy the damned thing compiled... I'm not where I can test it yet (physically, not at a machine capable of running FO4 at the moment, will be in a few hours) Link to comment Share on other sites More sharing options...
mfree80286 Posted March 30, 2017 Author Share Posted March 30, 2017 Little tweaks and it works, needed to use onBeginEvent with the states instead of onActivate because the latter required a button press for every state change. Also switched up the state targets for that first onactivate branch so TPadInactive is default and a successful press goes to TPadTransitionUp, that lets TPadInactive and TPadOffline just sit forever if need be. Stuck a sound script in the trigger box with an onTriggerEnter, going to test that out first and then it's on to teleporting. Link to comment Share on other sites More sharing options...
mfree80286 Posted March 31, 2017 Author Share Posted March 31, 2017 Just for reference, here are the tested functional scripts. Yes, they need improvement, but they step through the startup and shutdown processes and the trigger sends the player off to the other end with no discernible issues. Attached to trigger volume: Scriptname M1V201TeleportTriggerScript extends ObjectReference import Form Sound Property TeleportNoise auto ObjectReference Property RemoteTargetMarker auto Event onTriggerEnter(objectreference akTriggerRef) Actor PlayerRef = Game.GetPlayer() TeleportNoise.PlayAndWait(self) Utility.Wait(2.0) PlayerRef.MoveTo(RemoteTargetMarker, abMatchRotation = false) EndEvent Attached to button: Scriptname M1V201TeleportButton01 extends ObjectReference import Utility ObjectReference property TPTargetTerm auto ObjectReference property TPadTrigger auto ObjectReference property TPadLowLight auto ObjectReference property TPadMidLight auto ObjectReference property TPadReadyIndicator auto Event onInit() GoToState("TPadInactive") EndEvent EVENT onActivate (objectReference triggerRef) If(TPTargetTerm.isLocked()) GoToState ("TPadOffline") Else GoToState("TPadTransitionUp") EndIf EndEvent State TPadOffline Event OnBeginState(string asOldState) Debug.Notification("Device inactive - missing target data") TPadTrigger.disable() TPadLowLight.disable() TPadMidLight.disable() TPadReadyIndicator.PlayAnimation("Red") EndEvent EndState State TPadBusy EndState auto State TPadInactive Event OnBeginState(string asOldState) GoToState("TPadBusy") TPadTrigger.disable() TPadLowLight.disable() TPadMidLight.disable() TPadReadyIndicator.PlayAnimation("OFF") EndEvent EndState State TPadTransitionUp Event OnBeginState(string asOldState) GoToState("TPadBusy") TPadReadyIndicator.PlayAnimation("Yellow") Wait(3.0) TPadLowLight.Enable() Wait(3.0) TPadMidLight.Enable() Wait(3.0) GoToState("TPadActive") EndEvent EndState State TPadTransitionDown Event OnBeginState(string asOldState) TPadReadyIndicator.PlayAnimation("Yellow") Wait(3.0) TPadTrigger.Disable() TPadLowLight.Disable() Wait(3.0) TPadMidLight.Disable() Wait(3.0) GoToState("TPadInactive") EndEvent EndState State TpadActive Event OnBeginState(string asOldState) TPadReadyIndicator.PlayAnimation("Green") TPadTrigger.Enable() Wait(15.0) GoToState("TPadTransitionDown") EndEvent EndState Link to comment Share on other sites More sharing options...
Recommended Posts