AdmiralAlbia Posted June 14, 2018 Share Posted June 14, 2018 (edited) Background: Having never done it before, I decided to try and get my feet wet with Papyrus by fixing some minor annoyances in cpuLL's Myopia mod. Specifically, I wanted to cause the glasses to return to the inventory when dropped instead of falling on the floor and usually disappearing from the game forever - so the only change I needed to make was to comment out a single line of code and recompile. (I'd like to play around with adding things to its formlist too, but one problem at a time...) Here's the script, which is obviously cpuLL's work and not mine: Scriptname myopiaPlayerAlias extends ReferenceAlias FormList property MyopiaGlassesList Auto FormList property MyopiaForceSpellsList Auto ImageSpaceModifier property myopiaImageSpace Auto Quest property myopia Auto Actor property PlayerRef Auto GlobalVariable property MyopiaLoseGlassesOnHit Auto ; Used to configure the mod to lose the glasses or not when hit Armor currentGlasses int doneQuest = 0 ; 0=Not done & not initialized, 1=initialized, 2=completed Event OnInit() checkGlassesMods() if doneQuest==0 doQuestInit() endIf endEvent Event OnPlayerLoadGame() Utility.waitMenuMode(30.0) checkGlassesMods() if doneQuest==0 doQuestInit() endIf endEvent ; This function set up the quest, it is done (and re-checked) when the mod is initialized for the first time and when the game reloads ; The quest associated as just a few stages and objectives ; Stage 0, just init, say that the vision is blurry, for a minute don't do anything and let enjoy this strange new experience ; Stage 1, Add the objective "Get the glasses", and add visible markers to the three pairs of glasses available, when the actor gets atleastone pair of glasses we go to the next stage ; Stage 2, you just have to wear the glasses, and the objective will tell you that. Once you wear them for the first time the objective and the quest are completed (but you will get blurry vision every time you are NOT wearing the glasses) function doQuestInit() doneQuest=1 ; A couple of glasses is inside the Bee and Barb in Riften, another pair is in the kitchen of BanneredMare in Whiterun, another is in the WhinkingSkeever ; Wait a minute or two (randomly) and then force start the quest, start also altering the vision Utility.wait(Utility.randomFloat(180, 360)) ; This is a wait with a random time (in seconds) myopia.start() ; This starts the quest myopiaImageSpace.apply() ; This applyes the blurry and doubled vision myopia.setStage(0) ; Wait a little and then set the first stage and the temporary objective Utility.wait(60.0) ; A minute wait myopia.setStage(0) myopia.setObjectiveDisplayed(0) Utility.wait(60.0) ; Wait a minute like that, and then show the real objective (get the glasses) myopia.setObjectiveCompleted(0) myopia.setStage(1) myopia.setObjectiveDisplayed(1) endFunction ; This function checks if there are some known mods that add glasses, and add the glasses in the formlist function checkGlassesMods() if Game.GetModByName("_ImoMegane.esp")!=-1 addGlasses("_ImoMegane.esp", 0xD63) addGlasses("_ImoMegane.esp", 0x12CA) addGlasses("_ImoMegane.esp", 0x12CB) addGlasses("_ImoMegane.esp", 0x12CC) addGlasses("_ImoMegane.esp", 0x2DC0) addGlasses("_ImoMegane.esp", 0x2DC1) addGlasses("_ImoMegane.esp", 0x2DC2) addGlasses("_ImoMegane.esp", 0x2DC3) addGlasses("_ImoMegane.esp", 0x2DC4) addGlasses("_ImoMegane.esp", 0x2DC5) addGlasses("_ImoMegane.esp", 0x2DC6) addGlasses("_ImoMegane.esp", 0x2DC7) addGlasses("_ImoMegane.esp", 0x2DC8) addGlasses("_ImoMegane.esp", 0x332C) addGlasses("_ImoMegane.esp", 0x332D) addGlasses("_ImoMegane.esp", 0x3E01) addGlasses("_ImoMegane.esp", 0x3E02) addGlasses("_ImoMegane.esp", 0x3E03) addGlasses("_ImoMegane.esp", 0x3E04) addGlasses("_ImoMegane.esp", 0x3E05) addGlasses("_ImoMegane.esp", 0x3E06) addGlasses("_ImoMegane.esp", 0x3E07) addGlasses("_ImoMegane.esp", 0x3E08) addGlasses("_ImoMegane.esp", 0x3E09) addGlasses("_ImoMegane.esp", 0x3E0A) addGlasses("_ImoMegane.esp", 0x3E0B) addGlasses("_ImoMegane.esp", 0x3E0C) addGlasses("_ImoMegane.esp", 0x3E0D) addGlasses("_ImoMegane.esp", 0x3E0E) addGlasses("_ImoMegane.esp", 0x3E0F) endIf if Game.GetModByName("Dwemer Goggles & Scouter.esp")!=-1 addGlasses("Dwemer Goggles & Scouter.esp", 0xD63) addGlasses("Dwemer Goggles & Scouter.esp", 0x1829) addGlasses("Dwemer Goggles & Scouter.esp", 0x2857) addGlasses("Dwemer Goggles & Scouter.esp", 0x2DBE) addGlasses("Dwemer Goggles & Scouter.esp", 0x1A74F) addGlasses("Dwemer Goggles & Scouter.esp", 0x253FB) endIf debug.trace(">>> Glasses <<<<<<<<<<<<<<<<<<<<<<<<<<<<") int i = MyopiaGlassesList.GetSize() while i i-=1 string name = MyopiaGlassesList.GetAt(i).getName() debug.trace(">>> " + i + " <<< " + name + " >>> " + MyopiaGlassesList.GetAt(i)) endWhile endFunction ; Utility function to add a form to the form list by mod name and id0 function addGlasses(string mod, int id) Form glasses = Game.GetFormFromFile(id, mod) if !glasses return endIf if !MyopiaGlassesList.HasForm(glasses) MyopiaGlassesList.AddForm(glasses) endIf endFunction ; Event received when an item is added to this object's inventory. If the item is a persistant reference, akItemReference will ; point at it - otherwise the parameter will be None Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) ; In case the quest is completed or the stage is not the number 1, we have nothing to do if !myopia.IsRunning() || myopia.isCompleted() || myopia.getStage()!=1 return endIf ; Check if we have now a set of glasses if MyopiaGlassesList.hasForm(akBaseItem) ; OK, they are glasses, proceed to the next stage myopia.setStage(2) myopia.setObjectiveCompleted(1) myopia.setObjectiveDisplayed(2) doneQuest=2 endIf EndEvent ; Event received when this actor equips something - akReference may be None if object is not persistent Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) ; Check if what are we wearing is a pair of known glasses ; The valid list of glasses (they are Armors) is stored in the FormList if MyopiaGlassesList.hasForm(akBaseObject) ; yes, it is a valid pair of glasses, remove the myopia image space modifier myopiaImageSpace.remove() ; Keep track of the item currentGlasses = akBaseObject as Armor ; In case the quest was running and we were on the last stage, complete the quest if myopia.IsRunning() && !myopia.isCompleted() && myopia.getStage()==2 ; Complete the quest myopia.SetObjectiveCompleted(2) myopia.setStage(100) myopia.CompleteQuest() doneQuest=2 endIf endIf EndEvent ; Event received when this actor unequips something - akReference may be None if object is not persistent Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference) ; Check if we are removing a pair of knwon glasses 9they are in the formlist) if MyopiaGlassesList.hasForm(akBaseObject) ; yes, they were glasses, apply the myopia image space modifier myopiaImageSpace.Apply() ; Remove the current glasses item currentGlasses = None endIf EndEvent ; Event received when this object is hit by a source (weapon, spell, explosion) or projectile attack ; In case of a non-blocked heavy hit, or a Fus-Ro-Dah spell, we give a small possibility (about 10%) to lose the glasses Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) if abHitBlocked || MyopiaLoseGlassesOnHit.getValue()==0.0 return ; We will not lose the glasses if we block or if we have the global variable set to zero endIf Actor aggressor = akAggressor as Actor bool loseGlasses=false if aggressor int lh = aggressor.GetEquippedItemType(0) int rh = aggressor.GetEquippedItemType(1) if lh==1 || lh==3 || lh==4 || lh==5 || lh==6 || rh==1 || rh==3 || rh==4 || rh==5 || rh==6 ; Have a possibility to lose the glasses if hit by these weapons: 1 - One-handed sword; 3 - One-handed axe; 4 - One-handed mace; 5 - Two-handed sword; 6 - Two-handed axe loseGlasses=true endIf if (akSource as Spell) && MyopiaForceSpellsList.hasForm(akSource) ; Have a possibility to lose the glasses if hit by a Fus-Ro-Dah like spell loseGlasses=true endIf endIf if loseGlasses && currentGlasses ; Calculate the probability if Utility.randomFloat(0.0, 1.0)<0.05 ; 5% PlayerRef.unequipItem(currentGlasses, abPreventEquip=false, abSilent=false) ; Drop glasses onto floor - commented out because they always disappear from the world! ; PlayerRef.DropObject(currentGlasses, 1) endIf endIf EndEvent Several hours later... C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(52,12): GetModByName is not a function or does not exist C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(52,12): cannot call the member function GetModByName alone or on a type, must call it on a variable C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(52,42): cannot compare a none to a int (cast missing or types unrelated) C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(85,12): GetModByName is not a function or does not exist C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(85,12): cannot call the member function GetModByName alone or on a type, must call it on a variable C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(85,56): cannot compare a none to a int (cast missing or types unrelated) C:\Program Files (x86)\Steam\steamapps\common\Skyrim Special Edition\Data\source\scripts\myopiaPlayerAlias.psc(101,45): getName is not a function or does not exist No output generated for myopiaPlayerAlias.psc, compilation failed.I have already fixed the compiler's folder locations and extracted my Scripts.zip (hence why we're down to three errors), but I can't seem to get the compiler to recognise these fuctions. Tried changing GetModByName to IsPluginInstalled, as I couldn't find the former on the Creation Kit wiki (and, again, this is my first ever Papyrus scripting attempt), but that throws the same error. As I'm so new to this, I'm genuinely not sure if the problem is the code or the compiler, but I'm leaning towards the compiler. Having already extracted all my source scripts, though... how can I fix it? Edited June 14, 2018 by AdmiralAlbia Link to comment Share on other sites More sharing options...
IsharaMeradin Posted June 14, 2018 Share Posted June 14, 2018 GetModByName is a SKSE function. It therefore requires that SKSE be installed and the source scripts (PSC files) from SKSE be installed to the Data/Scripts/Source folder. Link to comment Share on other sites More sharing options...
AdmiralAlbia Posted June 15, 2018 Author Share Posted June 15, 2018 Mm, I suspected it might be... thing is, SKSE is installed and its sources are unpacked. And as I said, I changed the lines to IsPluginInstalled (a native function), and got the same 'not a function or does not exist' error. Also, I have to assume that getName is native? Link to comment Share on other sites More sharing options...
IsharaMeradin Posted June 15, 2018 Share Posted June 15, 2018 GetName is also SKSE Double check and make sure that you placed the SKSE PSC files in the same location as those from the scripts.rar file. Also, if you extracted the scripts.rar file after having installed SKSE, it will have overwritten the SKSE PSC files. Should that be the case, re-install them. To know if you have the correct files in place:Locate Form.psc and look for the function GetNameLocate Game.psc and look for the function GetModNameIf they are not on those scripts, you do not have the correct files in place. Link to comment Share on other sites More sharing options...
AdmiralAlbia Posted June 17, 2018 Author Share Posted June 17, 2018 Ahh, thank you! I think I had it installed to the wrong directory. All compiling now :) Link to comment Share on other sites More sharing options...
tonycubed2 Posted February 16, 2020 Share Posted February 16, 2020 IsharaMeradin you is a genius. this just helped me, MO2 makes it tricky Link to comment Share on other sites More sharing options...
Recommended Posts