TheNonsenseFactory Posted January 20, 2013 Share Posted January 20, 2013 Hi all, I have a problem with Disable not removing the object. Script included below. It is attached to an Activator type object. The expected behaviour:Before activation: nothing is shownFirst activation: WastelandFungusStalk05 is shownSecond Activation: WastelandFungusStalk01 is shownThird Activation: WastelandFungusStalk03 is shownFourth activation: nothing is shown, next activation is First again. The problem:Fungus does not disappear, they just keep piling up on top of eachother.WastelandFungusStalk03 appears one activation late. I have tried setting the CurrentPlant reference to Pencil01 (the oblivion "apple" trick) after disabling the current fungus, before setting the new fungus, but this crashes the game for me (!?). I have tried creating a cycle where not everything is done in the same frame, i.e. in each stage there is an internal counter that disables, sets, and enables in three different game frames. This makes the activator object disappear (!?). I am just about ready to commit hara-kiri with my keyboard, so any help is greatly appreciated! Thanks,The Nonsense Factory ScriptName TNF02PlantGrowth short DoOnce short CurrentStage int TimePlaceholder int TimePlanted int TimePassed ref PlantStage1aRef ref PlantStage2aRef ref PlantStage3aRef ref CurrentPlant Begin OnLoad if DoOnce == 0 set TimePlanted to TimePlaceHolder ;- - - create the different fungus objects - - - set PlantStage1aRef to PlaceAtMe WastelandFungusStalk05 set PlantStage2aRef to PlaceAtMe WastelandFungusStalk01 set PlantStage3aRef to PlaceAtMe WastelandFungusStalk03 ;- - - hide them for now - - - PlantStage1aRef.Disable 0 PlantStage2aRef.Disable 0 PlantStage3aRef.Disable 0 ;- - - don't do this again - - - set DoOnce to 1 endif end Begin OnActivate set TimePlaceHolder to TimePlaceHolder + 1 end Begin GameMode if DoOnce == 1 set TimePassed to TimePlaceHolder - TimePlanted if TimePassed < 1 ;- - - do nothing - - - elseif TimePassed == 1 if CurrentStage != 1 ;- - - do only once per stage - - - CurrentPlant.Disable 0 set CurrentPlant to PlantStage1aRef CurrentPlant.Enable 0 set CurrentStage to 1 endif elseif TimePassed == 2 if CurrentStage != 2 ;- - - do only once per stage - - - CurrentPlant.Disable 0 set CurrentPlant to PlantStage2aRef CurrentPlant.Enable 0 set CurrentStage to 2 endif elseif TimePassed == 3 if CurrentStage != 3 ;- - - do only once per stage - - - CurrentPlant.Disable 0 set CurrentPlant to PlantStage3aRef CurrentPlant.Enable 0 set CurrentStage to 3 endif elseif TimePassed > 3 ;- - - more time than 3 has passed - - - ;- - - plant should stay in current stage - - - ;- - - for testing purposes we reset the plant - - - set CurrentStage to 0 CurrentPlant.Disable 0 set TimePlanted to TimePlaceHolder endif endif end Link to comment Share on other sites More sharing options...
Xaranth Posted January 20, 2013 Share Posted January 20, 2013 Try this, and I'm not awake enough to coherently explain why, sorry: ScriptName TNF02PlantGrowth short DoOnce short CurrentStage int TimePlaceholder int TimePlanted int TimePassed ref PlantStage1aRef ref PlantStage2aRef ref PlantStage3aRef ref CurrentPlant Begin OnLoad if DoOnce == 0 set TimePlanted to TimePlaceHolder ;- - - create the different fungus objects - - - set PlantStage1aRef to PlaceAtMe WastelandFungusStalk05 set PlantStage2aRef to PlaceAtMe WastelandFungusStalk01 set PlantStage3aRef to PlaceAtMe WastelandFungusStalk03 ;- - - hide them for now - - - PlantStage1aRef.Disable 0 PlantStage2aRef.Disable 0 PlantStage3aRef.Disable 0 ;- - - don't do this again - - - set DoOnce to 1 Set CurrentStage to 1 endif end Begin OnActivate if DoOnce == 1 if CurrentStage == 1 CurrentPlant.Disable 0 set CurrentPlant to PlantStage1aRef CurrentPlant.Enable 0 set CurrentStage to 2 elseIf CurrentStage == 2 CurrentPlant.Disable 0 set CurrentPlant to PlantStage2aRef CurrentPlant.Enable 0 set CurrentStage to 3 elseif CurrentStage == 3 CurrentPlant.Disable 0 set CurrentPlant to PlantStage3aRef CurrentPlant.Enable 0 set CurrentStage to 4 elseif CurrentStage == 4 set CurrentStage to 0 CurrentPlant.Disable 0 Set CurrentStage to 1 endif endif end Link to comment Share on other sites More sharing options...
TheNonsenseFactory Posted January 20, 2013 Author Share Posted January 20, 2013 Thank you Xaranth for stepping in to help. I copied and pasted your version but it still does not work for me. For me this exhibits the same problems as my original script. Do you have the same issues, or is it my Fallout that has issues? The reason I have a more complex script, and want to run in GameMode instead of OnActivate is that this is intended to use GameDaysPassed as time instead of a simple activation counter (once I know it works). So a fungus will grow over a time of several days instead of a few clicks. Regards,The Nonsense Factory Link to comment Share on other sites More sharing options...
Xaranth Posted January 20, 2013 Share Posted January 20, 2013 Ohhh. I did wonder. I thought it might have been an attempt to shift things for troubleshooting. I don't know if it works as I did it, I ginned it up in notepad whilst drinking coffee. :) Uhm. Okay, part of it might be your reference variables aren't updating correctly. Is there a modularization reason you need to pass the plant refs to currentplant instead of working with them directly? If not, I would recommend simply calling enable/disable directly on your defined refVars. And possibly shift the whole thing into a quest script, to avoid onLoad headaches and weird behaviours. Link to comment Share on other sites More sharing options...
TheNonsenseFactory Posted January 20, 2013 Author Share Posted January 20, 2013 On 1/20/2013 at 12:28 PM, Xaranth said: ...Okay, part of it might be your reference variables aren't updating correctly. Is there a modularization reason you need to pass the plant refs to currentplant instead of working with them directly? If not, I would recommend simply calling enable/disable directly on your defined refVars. I do plan to modularize so that the same script can handle different plants, but that requires to set the plant refs anyway so it is not dependent on CurrentPlant. So I could work with the reference variables directly, it's just that it is so much less code to use CurrentPlant. Especially since I was sort of planning to have variations of each stage (hence the "a" in plant refs). Add a few more plant stages and it will be dozens of lines of code that are "uneccesary" if I could use CurrentPlant instead. On 1/20/2013 at 12:28 PM, Xaranth said: And possibly shift the whole thing into a quest script, to avoid onLoad headaches and weird behaviours.This is very interesting. What would the benefits be of using a quest script, and what would I have to take into consideration if I use one? I haven't really worked with quest scripts (I'm pretty much a GECK beginner). Regards,The Nonsense Factory Link to comment Share on other sites More sharing options...
Xaranth Posted January 20, 2013 Share Posted January 20, 2013 (edited) I think it would shorten the code, actually, unless you're using Cut/Paste. :) The onActivate block of my trial would look thus: Begin OnActivate if DoOnce == 1 if CurrentStage == 1 PlantStage1aRef.Disable 0 plantStage2aRef.Enable 0 set CurrentStage to 2 elseIf CurrentStage == 2 PlantStage2aRef.Disable 0 plantStage3aRef.Enable 0 set CurrentStage to 3 elseif CurrentStage == 3 plantStage3aRef.Disable 0 plantStage1aRef.Enable 0 set CurrentStage to 4 elseif CurrentStage == 4 plantStage1aRef.Disable 0 Set CurrentStage to 1 endif endif end A little more typing, but it uses less memory and processes faster. The benefits of using a questScript would primarily be persistence and portability (Across forms, I mean). Any script can access data stored in a questVariable, they're practically globals. Another is that you can slow down processing for performance gains. Let's be honest, you don't need to be processing that plant growth every frame. With the quest delay, you can tune the processing better. If you have a LOT of plants, you might also be a lot more successful modularizing the stuff by putting growth stuff in thequest script with generic vars, and then use activators to pass your plant data off to the quest. Finally, you can completely control questScript processing with StartQuest and StopQuest, allowing even more tightly tuned performance. Example: You want to grow plants in a dozen different 'greenhouses'. They're in different cells. You can use a qust script to control the enabling/disabling and stages, while storing the data you want to work with for each cell in an object script attached to a marker assigned to that cell. Edit: Dear God, that sounds like a pitch for OOP. Ugh. Edited January 20, 2013 by Xaranth Link to comment Share on other sites More sharing options...
TheNonsenseFactory Posted January 20, 2013 Author Share Posted January 20, 2013 On 1/20/2013 at 1:19 PM, Xaranth said: (snip) ... I think it would shorten the code, actually, unless you're using Cut/Paste. :) The onActivate block of my trial would look thus:It gets slightly more messy when you have variations a, b, c... etc of each plant stage because you do not know which one is enabled. If you keep track of which one you disabled, you get less of that. And if a lot of time passed between the checks, the plant may have gone from stage 1 to stage 3, so you have to disable all the other stages as well if you want it foolproof. One possible solution would be to keep track of when we last checked time, and determine if something is about to change, then disable everything. Then do the "if dance" to find out what we want to enable. That way we get only one copy of all the disabling. Or stick it all in the OnLoad section, so that we only do the calculations when we are actually about to see the plant. But, all that is just eye candy really. The big issue is that I can't disable stuff at all. I will have a go with the direct disable, like in your example, later today. It's totally worth dumping CurrentPlant to get it to work at all :) Regards,The Nonsense Factory Link to comment Share on other sites More sharing options...
Xaranth Posted January 20, 2013 Share Posted January 20, 2013 I don't like onLoad blocks. :pinch: In my experience they're unpredictable. Better to use a cubic activator and an onTriggerEnter to set a flag and a getInCell to unset it. I DO think the problem is probably related to refVar passing. So you probably need to use a staged timer of some sort (Not necessarily with getSecondsPassed, you could set a condition block and increment it every frame and wait four or five frames to tick it over) if you need to pass your 'to be maniuplated' objects back and forth. Link to comment Share on other sites More sharing options...
TheNonsenseFactory Posted January 22, 2013 Author Share Posted January 22, 2013 Success! The solution you suggested worked, by using the direct refereneces instead of using CurrentPlant, the plants are removed in an orderly fashion. Maybe not as elegant as I would have liked, but it works so I am happy. Thank again for your help! //The Nonsense Factory Link to comment Share on other sites More sharing options...
Xaranth Posted January 22, 2013 Share Posted January 22, 2013 Thought that might be it. Maybe we can petition the FOSE team for arrays and then you could do that the proper way. :P ...I really need to get off the Array hobbyhorse, I think. Link to comment Share on other sites More sharing options...
Recommended Posts