JonesenoJ Posted July 15, 2020 Share Posted July 15, 2020 Hello, as you've read in the title, could it be possibly done? I've looked around in the functions section and some forums but couldn't find anything. Thank you. Link to comment Share on other sites More sharing options...
IntenseMute Posted July 16, 2020 Share Posted July 16, 2020 You are looking for SetModelPathEx. You must also use Update3D for the changes to show any effect. Link to comment Share on other sites More sharing options...
JonesenoJ Posted July 16, 2020 Author Share Posted July 16, 2020 Thank you, now I can finally make my house upgradable and spend the 200k caps I've got. Link to comment Share on other sites More sharing options...
JonesenoJ Posted July 16, 2020 Author Share Posted July 16, 2020 The information about the function is really not well explained, is there a thread or guide I can read? Link to comment Share on other sites More sharing options...
IntenseMute Posted July 16, 2020 Share Posted July 16, 2020 (edited) To use this function you will need to know the difference between a "Base Object" and a "Reference to a Base Object".A Base Object does not exist in the game as a 3D object, it exists as a bunch of data that describes the object.A Reference to a Base Object is the individual 3D objects that exist in the game that can be interacted with, they use the data stored in the base object.See image. From my testing, this function only affects "References to Base Objects". That means that whatever items you want to modify, you are going to have to set a "Reference Editor ID". See step-by-step images on how to do that. After setting a "Reference Editor ID", just use the functions like this: ThisIsMyReference.SetModelPathEx "Clutter\Junk\Conductor.NIF" ThisIsMyReference.Update3D Or you can just follow this example, although it might be a little advanced. Int TemporaryInt Ref TemporaryRef Array_Var TemporaryArray Begin GameMode Let TemporaryArray := GetRefs 31, -1 Set TemporaryInt To Ar_Size TemporaryArray While -1 < (TemporaryInt -= 1) Let TemporaryRef := TemporaryArray[TemporaryInt] If TemporaryRef.GetBaseObject == FissionBattery SetModelPathEx "Clutter\Junk\Conductor.NIF" TemporaryRef TemporaryRef.Update3D EndIf Loop Ar_Null TemporaryArray End This script will look at all the MISC items around the player and if any of them are Fission Batteries it will set their item model to that of conductors. Edited July 16, 2020 by IntenseMute Link to comment Share on other sites More sharing options...
JonesenoJ Posted July 16, 2020 Author Share Posted July 16, 2020 Thank you for explaining it with such great detail. This is how my script looks now. String_Var "Furniture\Suburban\SubCouch01.NIF" if eval CouchREF.GetModelPath == "Furniture\Suburban\SubCouch01.NIF" Showmessage 01AlreadyDone Endif if eval CouchREF.GetModelPath == "Furniture\Suburban\SubCouchDirty01.NIF" && Player.GetItemCount Caps001 < 1000 Showmessage 01NoCaps Endif if eval CouchREF.GetModelPath == "Furniture\Suburban\SubCouchDirty01.NIF" && Player.GetItemCount Caps001 >= 1000 CouchREF.SetModelPathEx "Furniture\Suburban\SubCouch01.NIF" CouchREF.Update3D Showmessage 01AllDone Player.RemoveItem f 1000 Endif Btw i spent one hour looking for an error, turned out I used > instead of <. Link to comment Share on other sites More sharing options...
dubiousintent Posted July 17, 2020 Share Posted July 17, 2020 That sort of error is quite common, and a devil to find. One way to avoid it is to simplify your code wherever possible. For instance (rhetorical question), what is the difference between: if eval CouchREF.GetModelPath == "Furniture\Suburban\SubCouchDirty01.NIF" && Player.GetItemCount Caps001 < 1000 <action> endif if eval CouchREF.GetModelPath == "Furniture\Suburban\SubCouchDirty01.NIF" && Player.GetItemCount Caps001 >= 1000 <action> endif Answer: just the value being tested. And the choice of <action> is essentially an "If Caps001 < 1000 then <action1> ELSE <action2> EndIf". Now there is only one "condition value check" instead of two, but still multiple courses of <action>. If you were testing for which of three or more possible values of "Caps001", then it would be a "If <value1> ElseIf <value2> Else ... (must be something else, but is it unexpected?) ... EndIf". Because "Caps001" is only going to have one value at any given time and you are just trying to determine which. Remember: Every "IF" implies an "Else", even if not explicitly stated. This has bitten more than one new script writer. You can always have an "Else" spit out a "debug" message so you know it got there during development, and then strip it out later. Might have saved you an hour. -Dubious- Link to comment Share on other sites More sharing options...
JonesenoJ Posted July 17, 2020 Author Share Posted July 17, 2020 That would work if I didn't have 3 messages show up for each case. Link to comment Share on other sites More sharing options...
dubiousintent Posted July 18, 2020 Share Posted July 18, 2020 (edited) In principle it should not matter how many messages you have in each case. You can always set one or more variables to the correct message content to be displayed under each condition, and then use a single statement or block to display each "non-null" variable message. Simplest example: string sMsg ; initializes to "" Begin <block type> If <condition1> set sMsg to 01AlreadyDone ; other statements as appropriate Elseif <condition2> set sMsg to 01NoCaps ; other statements as appropriate Elseif <condition3> set sMsg to 01AllDone ; other statements as appropriate Else set sMsg to "No condition match" EndIf ShowMessage sMsg ; There should not be a "null" value of sMsg in this instance. End Another, related point:A simple condition test of variables is quite efficient. It's when you use a function call as part of a condition test that you are slowing things down and losing efficiency, because the processing has to "save it's place" and all the values of variables in use in the current script at the time, so it can go off and perform the function and then return that result as a temporary variable AFTER it resumes where it had left off.One of the problems with debugging "compound conditional tests" (e.g. "If <condition1> && <condition2>") is determining which of the conditions failed. But you have no way to determine what any function used in a conditional test returned. THAT variable is not one you defined. You are better off calling the function once before the conditional test, saving the result as a defined variable, and testing that variable as many times as needed thereafter. Even if you need to call the function several times, saving the result to a variable outside of a conditional test enables you to verify it returned something valid, which you can't do as part of the condition test itself. You want to make sure each component of your "compound" condition is working correctly before you combine them.-Dubious- Edited July 18, 2020 by dubiousintent Link to comment Share on other sites More sharing options...
Recommended Posts