icecreamassassin Posted March 22, 2017 Author Share Posted March 22, 2017 Ok, so I am going to give you the compiler error because you seem to think I'm doing it all wrong here, but your GetBaseObject() useage is wrong looks like the line 152 simply doesn't need GetBaseObject(). I'll see if it functions in game this way. Starting 1 compile threads for 1 files...Compiling "DBM_PrepstationScript2Extender"...C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(153,11): GetBaseObject is not a function or does not existC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(153,27): cannot cast a none to a armor, types are incompatibleC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(182,15): GetBaseObject is not a function or does not existC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(182,31): cannot cast a none to a armor, types are incompatibleC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(220,15): GetBaseObject is not a function or does not existC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(220,31): cannot cast a none to a armor, types are incompatibleC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(258,15): GetBaseObject is not a function or does not existC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(258,31): cannot cast a none to a armor, types are incompatibleC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(259,77): variable jcRef is undefinedC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(259,83): none is not a known user-defined typeC:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(259,100): cannot compare a none to a int (cast missing or types unrelated)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepstationScript2Extender.psc(259,100): cannot relatively compare variables to None\ Link to comment Share on other sites More sharing options...
icecreamassassin Posted March 22, 2017 Author Share Posted March 22, 2017 Ok, so scratch any issues on the extender script, just a few oversights on your original like jcRef was supposed to be Jc2Ref instead and the getbaseobject calls were not needed in those instances (or the as armor has to be called on the formlist getat() call, not sure, we'll see if it works properly) So then trying to compile your reworked child script, it still has issues with failing to cast ActionRef The issue seems to be (at least if I am understand it properly), The OnActivate event it filling ActionRef as an objectreference but your functions need to call it as an actor. Either that or like I mentioned before, ARef is NOT defined anywhere inside the script other than inside the Armory block which runs separate from the rest and thus does not carry that function property out Starting 1 compile threads for 1 files...Compiling "DBM_PrepStationScript2"...C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(198,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(201,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(204,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(211,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(214,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(217,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(220,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(227,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(257,4): type mismatch on parameter 1 (did you forget a cast?)C:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\DBM_PrepStationScript2.psc(260,4): type mismatch on parameter 1 (did you forget a cast?)No output generated for DBM_PrepStationScript2, compilation failed.Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on DBM_PrepStationScript2 Link to comment Share on other sites More sharing options...
icecreamassassin Posted March 22, 2017 Author Share Posted March 22, 2017 Oh and lastly, you didn't explain why you prefer using Game.GetPlayer() when several people have attested to me over the last couple years that setting a property for it is 1000 times faster. Incidentally if I do set a PlayerRef property and replace your ActionRef function property in the child script to pass the PlayerRef through to the parent script as the first parameter in each of the sort functions, it compiles just fine. Can to explain clearly why this would not work the best? because as the script looks, there is NOTHING telling the normal state OnActivate event what ActionRef even is because it can't pass an objectreference through as an actor (which is why is causing the type mismatch as best I can tell). I am fascinated by the array method you are eluding to in the script and in your last post. Are Arrays a much faster method to indexing data? faster than formlists or individual properties? Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 22, 2017 Share Posted March 22, 2017 I am fascinated by the array method you are eluding to in the script and in your last post. Are Arrays a much faster method to indexing data? faster than formlists or individual properties?Arrays are only faster when a formlist contains more than 128 entries. Otherwise an array and a formlist process pretty much the same. The only difference being that arrays can contain INT, FLOAT & STRING whie formlists can only contain forms of one or multiple types. ReDragon2013's array function in the post you indicated simply removes your individual checks for mods into a string array of mod names that then set an index matching bool array with true false values so that you can just check for that stored value rather than calling GetModByName throughout each script run. If called in an OnInit event and then remotely from an OnPlayerLoadGame event, you can reduce the OnActivate processing time a little bit while maintaining valid bool values in the array. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted March 25, 2017 Share Posted March 25, 2017 (edited) icecreamassassin wrote: "Oh and lastly, you didn't explain why you prefer using Game.GetPlayer() when several people have attested to me over the last couple years that setting a property for it is 1000 times faster." The fairytale was written in year 2012, Charles Cooley aka CDCooley wrote:"Game.GetPlayer() function takes approximately 1000 times longer to run than just accessing a property set to PlayerRef."You'll find his mod "PapyrusSpeedTest" here: http://www.nexusmods.com/skyrim/mods/18825/?And here you'll find a posting by Perdev, which explained why this is a fairytale. http://forums.bethsoft.com/topic/1383987-performance-characteristics-of-papyrus-functions-and-operations/page-2 I made my own speedtest, the while counter "i" is 7. "bLoop" is a scriptVariable, declared like that Bool bLoop playerRef ;======================== State Test11 ;=========== FUNCTION myF_Test() sTest = "fm = playerRef.GetBaseObject()" actor playerRef = Game.GetPlayer() form fm int i = ff.Length WHILE (bLoop) i = i - 1 ff[i] = Utility.GetCurrentRealTime() fm = playerRef.GetBaseObject() bLoop = (i > 0) ENDWHILE ENDFUNCTION ;======= endState ;======================== State Test18 ;=========== FUNCTION myF_Test() sTest = "playerRef = None" actor aRef = Game.GetPlayer() actor playerRef = aRef int i = ff.Length WHILE (bLoop) i = i - 1 ff[i] = Utility.GetCurrentRealTime() ;;; playerRef = aRef playerRef = None bLoop = (i > 0) ENDWHILE ENDFUNCTION ;======= endState Game.GetPlayer() ;======================== State Test8 ;=========== FUNCTION myF_Test() sTest = "aRef = Game.GetPlayer()" actor aRef int i = ff.Length WHILE (bLoop) i = i - 1 ff[i] = Utility.GetCurrentRealTime() aRef = Game.GetPlayer() bLoop = (i > 0) ENDWHILE ENDFUNCTION ;======= endState I used a quest script which runs on intro scene in fresh new game: [03/24/2017 - 05:08:49AM] Test 0: empty loop 1.0 ms = 0.001 sec [03/24/2017 - 05:08:49AM] completed in 27.285984 ms, max = 0.055000, min = 0.000000 sec average = 0.027200 [03/24/2017 - 05:08:50AM] [03/24/2017 - 05:08:50AM] Test 1: s = "sample" [03/24/2017 - 05:08:50AM] completed in 30.857086 ms, max = 0.057999, min = 0.017002 sec average = 0.028200 [03/24/2017 - 05:08:50AM] [03/24/2017 - 05:08:50AM] Test 2: f = GameDaysPassed.value [03/24/2017 - 05:08:50AM] completed in 32.143185 ms, max = 0.070999, min = 0.021000 sec average = 0.026601 [03/24/2017 - 05:08:50AM] [03/24/2017 - 05:08:50AM] Test 3: f = GameDaysPassed.GetValue() = 0.296444 [03/24/2017 - 05:08:50AM] completed in 36.857059 ms, max = 0.062000, min = 0.017998 sec average = 0.035600 [03/24/2017 - 05:08:51AM] [03/24/2017 - 05:08:51AM] Test 4: i = GameDaysPassed.GetValueInt() [03/24/2017 - 05:08:51AM] completed in 36.143166 ms, max = 0.060001, min = 0.021000 sec average = 0.034400 [03/24/2017 - 05:08:51AM] [03/24/2017 - 05:08:51AM] Test 5: if GameDaysPassed as GlobalVariable | endif [03/24/2017 - 05:08:51AM] completed in 24.285997 ms, max = 0.063999, min = 0.000000 sec average = 0.021201 [03/24/2017 - 05:08:52AM] [03/24/2017 - 05:08:52AM] Test 6: s = Debug.GetVersionNumber() [03/24/2017 - 05:08:52AM] completed in 52.428108 ms, max = 0.081001, min = 0.000000 sec average = 0.057199 [03/24/2017 - 05:08:53AM] [03/24/2017 - 05:08:53AM] Test 7: f = Utility.GetCurrentGameTime() [03/24/2017 - 05:08:53AM] completed in 41.714260 ms, max = 0.080997, min = 0.000000 sec average = 0.042200 [03/24/2017 - 05:08:53AM] [03/24/2017 - 05:08:53AM] Test 8: aRef = Game.GetPlayer() [03/24/2017 - 05:08:53AM] completed in 63.142502 ms, max = 0.082001, min = 0.040001 sec average = 0.063999 [03/24/2017 - 05:08:54AM] [03/24/2017 - 05:08:54AM] Test 9: oRef = Game.GetForm(0x14) as ObjectReference [03/24/2017 - 05:08:54AM] completed in 34.857067 ms, max = 0.053001, min = 0.017998 sec average = 0.034600 [03/24/2017 - 05:08:55AM] [03/24/2017 - 05:08:55AM] Test 10: oRef = Game.GetPlayer() as ObjectReference [03/24/2017 - 05:08:55AM] completed in 67.000252 ms, max = 0.080002, min = 0.046001 sec average = 0.068600 [03/24/2017 - 05:08:55AM] [03/24/2017 - 05:08:55AM] Test 11: fm = playerRef.GetBaseObject() [03/24/2017 - 05:08:55AM] completed in 63.000271 ms, max = 0.077999, min = 0.046997 sec average = 0.063201 [03/24/2017 - 05:08:56AM] [03/24/2017 - 05:08:56AM] Test 12: AB = playerRef.GetActorBase() [03/24/2017 - 05:08:56AM] completed in 59.999737 ms, max = 0.081001, min = 0.030998 sec average = 0.061600 [03/24/2017 - 05:08:56AM] [03/24/2017 - 05:08:56AM] Test 13: if fm as Actor | endif [03/24/2017 - 05:08:56AM] completed in 31.428747 ms, max = 0.073002, min = 0.013000 sec average = 0.026800 [03/24/2017 - 05:08:57AM] [03/24/2017 - 05:08:57AM] Test 14: fx = Game.GetPlayer().X [03/24/2017 - 05:08:57AM] completed in 86.714607 ms, max = 0.119003, min = 0.044998 sec average = 0.088600 [03/24/2017 - 05:08:58AM] [03/24/2017 - 05:08:58AM] Test 15: fx = playerRef.X [03/24/2017 - 05:08:58AM] completed in 54.714203 ms, max = 0.084999, min = 0.025002 sec average = 0.054600 [03/24/2017 - 05:08:59AM] [03/24/2017 - 05:08:59AM] Test 16: fz = Game.GetPlayer().GetPositionZ() [03/24/2017 - 05:08:59AM] completed in 80.428535 ms, max = 0.097000, min = 0.035999 sec average = 0.086000 [03/24/2017 - 05:08:59AM] [03/24/2017 - 05:08:59AM] Test 17: fz = playerRef.GetPositionZ() [03/24/2017 - 05:08:59AM] completed in 53.999763 ms, max = 0.093998, min = 0.024002 sec average = 0.052000 [03/24/2017 - 05:09:00AM] [03/24/2017 - 05:09:00AM] Test 18: playerRef = None [03/24/2017 - 05:09:00AM] completed in 25.571550 ms, max = 0.066002, min = 0.012001 sec average = 0.020200 [03/24/2017 - 05:09:01AM] [03/24/2017 - 05:09:01AM] Test 19: f = playerRef.GetHeight() [03/24/2017 - 05:09:01AM] completed in 57.143074 ms, max = 0.102001, min = 0.022999 sec average = 0.055000 Let us assume playerRef would be 1000 times faster than Game.GetPlayer(), what would be happen?If PlayerRef would need 1.0 ms, so Game.GetPlayer() may run only every 1.0 s, that is ridiculous.Game.GetPlayer() is going to slow down your scripts if you call it in a while loop over and over again, but you have to call it more than 6 times before the game engine lower the script priority (in my experience).In worst case it runs 100 times/percent slower (it consumes the double time), which is the difference from 30.0 ms up to 60.0 ms, which are 0.030 seconds.Do you think this is much time? Edited March 26, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted March 25, 2017 Share Posted March 25, 2017 (edited) actionRef, Why can I be sure that is the player? vanilla like events: EVENT OnActivate(ObjectReference akActionRef) ENDEVENT EVENT OnTriggerEnter(ObjectReference akActionRef) ENDEVENTI prefer the next, do not ask me why? EVENT OnActivate(ObjectReference actionRef) ENDEVENT EVENT OnTriggerEnter(ObjectReference triggerRef) ENDEVENTand now the trick: EVENT OnActivate(ObjectReference actionRef) IF (actionRef == Game.GetPlayer() as ObjectReference) ELSE RETURN ; - STOP - not activated by the player ENDIF ;-------------- from here the actionRef is always the player as ObjectReference actor aRef aRef = actionRef as Actor ; speed up aRef = Game.GetPlayer() ; slower speed while using Game.GetPlayer() a second time ENDEVENTI hope it explained the using of actionRef. Edited March 25, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted March 25, 2017 Share Posted March 25, 2017 (edited) I do not use SKSE, so it is impossible to compile such scripts by me. The next function could be useful, if you check players inventory once only (SKSE is required). Form[] PROPERTY InventoryList auto Hidden Int counterIL ;--------------------------------------- FUNCTION myF_SKSE_StorePlayerInventory() ;--------------------------------------- ; http://www.creationkit.com/index.php?title=GetNthForm_-_ObjectReference actor aRef = Game.GetPlayer() InventoryList = new Form[128] ; max. array size counterIL = 0 int i = aRef.GetNumItems() ; SKSE WHILE (i > 0) && (counterIL < 127) i = i - 1 form fm = aRef.GetNthForm(i) ; SKSE IF (fm as Weapon) || (fm as Armor) InventoryList[i] = fm ; store that form for comparison later counterIL += 1 ; update array counter ENDIF ENDWHILE ENDFUNCTION The question is: Does it makes sense to store players inventory? Can we really decrease the script runtime? Edited March 25, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
icecreamassassin Posted March 25, 2017 Author Share Posted March 25, 2017 Thanks for the time test info, that's very informative. I think you are misunderstanding me about ActionRef usage. I understand HOW it's supposed to work, the issue is that the way you wrote it, it DOESN'T work. The child script will not compile and says that actionref is not the right type and that it's failed to cast. So if you could look again and see where actionref is supposed to be defined for the function blocks that'd be very helpful because as it stands it's not compiling and the only solution I have tried which works is to cast actionref = game.getplayer() right before the sort function groups run Link to comment Share on other sites More sharing options...
ReDragon2013 Posted March 25, 2017 Share Posted March 25, 2017 (edited) You wrote: "The child script will not compile and says that actionref is not the right type and that it's failed to cast." That is interesting: EVENT OnActivate(ObjectReference actionRef) IF (actionRef == Game.GetPlayer()) ; this is working without typecast, because actor is always of type objectReference ELSE RETURN ; - STOP - ENDIF ;--------------------------- I forgot the typecast !! myF_Test(actionRef as Actor) ; typecast is needed, because not every objectReference can be an actor ENDEVENT FUNCTION myF_Test(Actor aRef) ;---------------------------- ; do nothing ENDFUNCTIONIf you need more advise for your monster script, I think it is a good idea to post your current version of script(s) here again. Did you notice, some functions are redundant? Edited March 26, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
icecreamassassin Posted March 26, 2017 Author Share Posted March 26, 2017 Alrighty so I stuck in the myF_Test(actionRef as Actor) into the activation event and stuck the function for it in the parent script and they both compile fine now. I'll set it up again and test to see what's what. If I have any issues I'll post back. I did notice the first time through I was getting a ton of stack errors on your myF_SortByMod function, which I'll have to look into, but I'll post if I can't figure out the cause. I suspect it's just running code without conditioning out that the mod isn't loaded. EDIT: Looks like the errors have resolved, so all should be good. Doing tests now. Link to comment Share on other sites More sharing options...
Recommended Posts