Jump to content

Problem with Disabled objects not disappearing


Recommended Posts

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 shown

First activation: WastelandFungusStalk05 is shown

Second Activation: WastelandFungusStalk01 is shown

Third Activation: WastelandFungusStalk03 is shown

Fourth 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

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

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

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

  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

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 by Xaranth
Link to comment
Share on other sites

  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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...