SKKmods Posted September 20, 2017 Share Posted September 20, 2017 (edited) I have a quest that involves visiting a bunch of unmarked wilderness locations, defined with Xmarkerrefs. The Target Ref quest map markers show on the map through the Alias Refs fine. The problem is defining the objective/stage completion when the player gets to them. No killing or picking up stuff, just "visit the location" and enjoy the view. None of the location based condition functions or code methods wants to work on an Alias or Objref. Is there an easy way to establish a "player has visited location" quest objective completion, or should I not be using Xmarkerrefs ? IsCleared() - type mismatch.IsSameLocation - type mismatch.IsInSameCurrentLocAsRef - no viable input I have poked around the MQ/BOS quests and still cant figure it out. /brain-hurty Edited September 20, 2017 by SKK50 Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 21, 2017 Share Posted September 21, 2017 One option would be to put a trigger box around the area and script on it to update the quest with info stating that player visited that spot. Either using a global counter for how many spots you have, then just setting the objective complete, or you could use unique globals for each spot if you need some way to know which ones have been visited. That could allow you do script setting the global prior to the quest triggering, then have the quest check the global before setting the destination objectives. Unless you want to force the player to goto the spot only after starting the quest. In which case you would want your trigger script to also have a check if your quest is running and/or on an appropriate stage. The trigger should also turn itself off (preferably using states or disable+delete) once triggered. Link to comment Share on other sites More sharing options...
SKKmods Posted September 21, 2017 Author Share Posted September 21, 2017 (edited) Trigger Volume - fantastic, haven't used them yet so will try out. Appreciated. & Later: Trigger volumes do the job great (memo: common activator, individual scripts, set primitive collision layer L_TRIGGER). Cant figure out how to disable a trigger after it has fired, so use a silent objective get/set per location as a unique flag placeholder. Edited September 21, 2017 by SKK50 Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 22, 2017 Share Posted September 22, 2017 (edited) Trigger Volume - fantastic, haven't used them yet so will try out. Appreciated. & Later: Trigger volumes do the job great (memo: common activator, individual scripts, set primitive collision layer L_TRIGGER). Cant figure out how to disable a trigger after it has fired, so use a silent objective get/set per location as a unique flag placeholder. The way I do it is something like this: Scriptname demoTriggerWithDisable Extends ObjectReference Quest Property pQuestToFire Auto Const Int Property iStageToSet Auto Const GlobalVariable pSomeGlobalValue Auto Const Auto State Waiting Event OnTriggerEnter(ObjectReference akActionRef) ; error validation if pQuestToFire && iStageToSet GotoState("Finished") ; this will ensure any further entering of the trigger box doesn't do anything. pQuestToFire.SetStage(iStageToSet) Disable() ; just for good measure endif ; optionally/as well do something with the global if pSomeGlobalValue pSomeGlobalValue.Value = pSomeGlobalValue.Value + 1 endif EndEvent EndState State Finished ; intentionally empty EndState I haven't tried to compile this as I wrote it quickly from memory. The idea is that you set the quest and stage and/or the global and they can operate independently. The script can then be used generically on a single type of activator and then property specifics set on the individual object refs when placed. You could also add a Delete() or DeleteWhenAble() after the Disable() if you wanted the ref to be fully killed and removed. I leave them in case there's a circumstance that comes up where I might need to edit the script and re-enable the trigger for some reason. Edited September 23, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
SKKmods Posted September 22, 2017 Author Share Posted September 22, 2017 Nice, that will save constant if statement processing. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 22, 2017 Share Posted September 22, 2017 (edited) Nice, that will save constant if statement processing. Another thread I just happened across suggested an alternative to the auto state. Using the OnInit in the empty state to set the waiting state instead. In the use case for this script I'm not sure if there is any appreciable difference in the effect of the script. Just thought I'd mention it. Edited September 22, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
SKKmods Posted September 22, 2017 Author Share Posted September 22, 2017 For completeness I now have a stack of these running L_TRIGGER activators for multiple marked objectives in a single stage. Really do appreciate the help. Auto State Wating Event OnTriggerEnter(ObjectReference akActionRef) Debug.Trace( Self + " firing on " + akActionRef ) If ( akActionRef == Game.GetPlayer()) && pSKK_MQ.IsRunning() GotoState("Finished") Disable() Float fCount = pSKK_MQCounterHostile.GetValue() fCount += 1 pSKK_MQCounterHostile.SetValue(fCount) Debug.Notification( "You have cleared " + ( fCount as Int) + " of the hostile locations." ) Debug.Trace( Self + " set SKK_MQCounterHostile to " + fCount ) EndIf If ( pSKK_MQ.GetStage() == 40 ) && ( pSKK_MQCounterHostile.GetValue() >= 6 ) pSKK_MQ.SetStage(50) EndIf EndEvent EndState State Finished ;void EndState Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 23, 2017 Share Posted September 23, 2017 Looks good. One more thing I'd like to add. It would be good practice to replace your Debug.Notification with a Message.Show. If you ever planned to release this to Xbox they don't have debug functions at all. Also for final release you'd want to either comment out Debug lines or compile the scripts with the release flag so it strips them out. Having the vm run Debug functions puts a tangible hit on performance not just for your scripts, but all running scripts since they all share the same allotment for time to run per frame. To do the message stuff.In CK create a new message.Uncheck it as a messagebox type.In the title box put your one liner message "You have cleared %.0f of the hostile locations."Then in your code define a property for the message.Use the messageProperty.Show(fCount) instead of the Debug.Notification. Link to comment Share on other sites More sharing options...
SKKmods Posted September 23, 2017 Author Share Posted September 23, 2017 With the basic mechanics running, optimisations to follow including replacing Game.GetPlayer() and such. Right now most of my time is spent working around rubbish documentation by looking at debug output. A lot of debug output. Link to comment Share on other sites More sharing options...
Recommended Posts