MegaStorm Posted December 14, 2017 Author Share Posted December 14, 2017 A personal butler script is a nice idea. Having somebody/thing check your well being every X interval is first class. The ultimate custom experience ^_^ Btw MegaStorm were you a MUD programmer? Timers in "livings" were called heartbeats. Haven't heard that in awhile. Not MUD (had to Google that! :cool:), but I am a software engineer. C, C++, C#, Java, JavaScript, most of the various now arcane languages (Fortran, Ada, Pascal, Cobol, Lisp [though this isn't really arcane, I guess], Prolog, etc.), and more assembly languages than I care to count. No, heartbeat task running in the background is a common feature in most diagnostic subsystems: something that monitors the system and does self-tests periodically. That was my idea for my mod back in Fallout 3, hence the name/description. :happy: Link to comment Share on other sites More sharing options...
ThoraldGM Posted December 14, 2017 Share Posted December 14, 2017 Well, semantics. You can ForceRefTo if the script is placing player into alias. Or you can place/assign manually in CK, then add/attach a script afterward. ForceRefTo: https://www.creationkit.com/fallout4/index.php?title=ForceRefTo_-_ReferenceAlias Quest Aliases (Skyrim version. FO4 wiki is bare on that): https://www.creationkit.com/index.php?title=Quest_Alias_Tab However, I think a butler script can be simpler than that. Make a quest. Checkbox start game enabled. Add a script to quest in CK. Then park your event sniffers there, like RegisterForRemoteEvent. Since it is remote, no other connection to player is required. And your script will always be running/listening for whatever events you place in it. Link to comment Share on other sites More sharing options...
SMB92 Posted December 14, 2017 Share Posted December 14, 2017 You can setup a ReferenceAlias on your quest, and in that you can hold data to apply to whatever you fill it with, such as AI pacakges, scripts, keywords, etc. But you don't actually have to fill it. Using ForceRefTo() will put the player (or whatever other reference) into the Alias, whereas using ApplyToRef just applies the data from the Alias to the player (or other reference). Later you use RemoveFromRef to remove the data if you so choose. There's a couple flags you need to check in the Alias to be able to do the latter, I don't have CK available right now and I have a memory like a sieve so I'll tell you them later. You can attach any kind of script to the Alias, so that way you can attach a script of your Objects type (in this case, namely Actor). Once the player is in the Alias, or has the Alias data applied (so script attached), you should be able to refer directly to any properties and functions on the script through the player reference. Here is a very basic example: EDIT: I hate how apostrophes and commas turn all text after them pink :sad: Fixed. This method uses the ApplyToRef() method. Later we can RemoveFromRef() to take the data away again. This method is good for avoiding unnecessary persistence (pointless for player though) and also creating unique instances of scripts. EDIT2: Lol just saw Thorlads last post. Thatmethod is fine also. Like I say so many ways to skin a cat. Scriptname MyQuestScript extends Quest Actor Property Player Auto ;Property of the player, you could make this Const or fill it at runtime. Either way when the quest stops, it is unfilled ReferenceAlias Property MyPlayersDataAlias Auto Const ;Just in case you didnt know the Const flag means this cannot be changed by any script - its set in stone. Event OnInit() MyPlayersDataAlias.ApplyToRef(Player) ;All the data in the Alias is attached to the Player. Player.BeginMyCode() ;Now that the script that extends Actor on the Alias is applied to player, we shou;d be able to access it directly. So this function exists on that script EndEvent ;Now here you could put whatever you need. You could use this script as a point of control to hold properties ;or functions, and have your 2 scripts communicate between each other. Link to comment Share on other sites More sharing options...
MegaStorm Posted December 14, 2017 Author Share Posted December 14, 2017 However, I think a butler script can be simpler than that. Make a quest. Checkbox start game enabled. Add a script to quest in CK. Then park your event sniffers there, like RegisterForRemoteEvent. Since it is remote, no other connection to player is required. And your script will always be running/listening for whatever events you place in it. Well, yeah, I had that going from the get-go, and as I reported back in my 2nd post, my simply starting a timer in the initial (and one-time only) OnQuestInit() call seems to persist across game sessions. The solution I am looking for, though, is to be able to detect when my mod initially loads, i.e., when I first load a save game. Alas, with the changes in the engine, I'm thinking I'm going to have just bite the bullet and maybe give my player self some custom object or something. I would still like to know, though, about how to go about aliasing the player like you guys (and other posts) talk about. Citing the wiki page is no helpful because that give zero context to the setup involved. For instance, your most recent wiki reference simply cites Alias_JohnDoe.ForceRefTo(self) :huh: I guess maybe change that to Game.GetPlayer().ForceRefTo(self)? Wiki is not very clear or detailed. Link to comment Share on other sites More sharing options...
MegaStorm Posted December 14, 2017 Author Share Posted December 14, 2017 @SMB92, you ninja'd me. :cool: I'm reading your post now... Link to comment Share on other sites More sharing options...
SMB92 Posted December 14, 2017 Share Posted December 14, 2017 Think of the Alias as an object, that is nothing, but has all this data attached to it. Then you're assigning your player to be that object and it inherits all the data. The Apply method I mentioned just gives the data to the player, without your player being assigned to it. I just thought it would be beneficial to you to use the Alias because you can attach a script that directly extends the type (Actor) and therefore allow you to directly listen for the events it naturally receives. Edit: ninjad you again :) Link to comment Share on other sites More sharing options...
ThoraldGM Posted December 14, 2017 Share Posted December 14, 2017 This thread needs a basic example of a quest utility script, and a CK screenshot of filling a quest alias for player. Unfortunately I am on phone browser waiting for my son to stop hogging the comp with CK on it. Link to comment Share on other sites More sharing options...
SMB92 Posted December 14, 2017 Share Posted December 14, 2017 Ya I'm on phone as well. Snuck a minute in to write that basic example above on work pc. Will be leaving shortly to go get on a hot roof and look for a signal for an antenna :( Link to comment Share on other sites More sharing options...
MegaStorm Posted December 14, 2017 Author Share Posted December 14, 2017 This thread needs a basic example of a quest utility script, and a CK screenshot of filling a quest alias for player. Unfortunately I am on phone browser waiting for my son to stop hogging the comp with CK on it. Speaking of that, I've been looking through the game's quests/scripts, and the AO_Dogmeat_FindItem quest seems to provide an example of how to setup a reference to the player. Of course, neither of the two attached scripts reference that reference, so maybe not...... Anyway, I'll keep digging through Bethesda's game code. Certainly, there is something there that mimics what I am trying to accomplish. Link to comment Share on other sites More sharing options...
MegaStorm Posted December 14, 2017 Author Share Posted December 14, 2017 Eureka! The HC_Manager quest (and, more importantly, its script) showed me the simple thing that I was doing wrong. So, ThoraldGM, you were exactly right in that I needed to register for the OnPlayerLoadGame event, but my mistake was in how I was defining the event handler. Original Event OnPlayerLoadGame(actor aSender) MyTrace( "OnPlayerLoadGame()" ) EndEvent This yields the "script must be native" errors I was talking about. Updated Event Actor.OnPlayerLoadGame(actor aSender) MyTrace( "Actor.OnPlayerLoadGame()" ) EndEvent (For those who can immediately see the difference, note that I originally left out the Actor base class.) So for posterity, here's the bare-bones script: Scriptname Neutrino:MainScript extends Quest String property g_szScriptName = "Neutrino:MainScript" auto const Actor PlayerRef Event OnInit() MyTrace( "OnInit()" ) PlayerRef = Game.GetPlayer() RegisterForRemoteEvent( PlayerRef, "OnPlayerLoadGame" ) OnGameStart() EndEvent Event Actor.OnPlayerLoadGame(actor aSender) MyTrace( "Actor.OnPlayerLoadGame()" ) OnGameStart() EndEvent Function OnGameStart() MyTrace( "OnGameStart()" ) String szMsg = "Player has " + PlayerRef.GetGoldAmount() + " caps." MyTrace( szMsg ) EndFunction Function MyTrace( String p_szMsg ) String szMsg = "[" + g_szScriptName + "] " + p_szMsg; Debug.Trace ( szMsg ) Debug.MessageBox ( szMsg ) Debug.Notification( szMsg ) EndFunction In the above, I'll add back my timer event and also register for and override any other applicable event (OnHit, OnItemEquipped, OnItemAdded, etc.) Thanks, guys!! Link to comment Share on other sites More sharing options...
Recommended Posts