Announcement

Collapse
No announcement yet.

DP Triggerable Weather 2.0

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DP Triggerable Weather 2.0

    I am not actually posting this to attribute to a finished work. Yesterday I posted a tutorial oon how to disassemble qc to create custom ent definitions. I used my triggerable weather as example code. In that, I realized that some code written by others was not actually necessary. I also realized that I left unfinished ideas in my code AND I had 2 mistakes (mine).

    I removed the unnecessary/unfinished code and corrected my mistakes. I also commented the code. If you start with the bottomest function and then cascade that scope up through all of the above functions, it becomes really clear how everything works. I also rewrote the ent definition to reflect the changes.

    All that being said, I am posting this so others can learn stuff. These two codes hold a lot of different examples within them, like:

    How to create a custom trigger
    How to check and set variables
    How to derive an ent definition from QC
    How to set/create/use spawnflags

    and I'm sure more. If you are using my modified np++ you will have a very easy time reading the code.

    ___

    For those of you that actually want to use this code: First of all you will need DPExtensions.qc compiled into your progs.dat (as well as my code). You will also have to add my ent definition to your entities.ent. From there you would open up your map in radiant and draw a brush where you want weather to be. Then right click it (while it is selected) and select func/func_weather. From here you have options.

    1) do nothing else and by default it will automatically rain
    2) select the rain or snow spawnflag and by default it will automatically create that
    3) give the weather a targetname, create a trigger and assign the targetname of the weather to the target of the trigger. The weather will start as off by default, but when you touch your trigger it will turn on. Depending on the type of trigger or how many triggers that you use, you can turn the weather on and off. Whatever the forecast is, it will be the opposite when you hit the trigger.



    save as weather.qc, add to progs.src at the very bottom, compile
    Code:
    /*__________>  		TRIGGERABLE WEATHER - BUILD 20130419		 <__________*/
    /*      		  modified from Lord Havoc's rain and snow       			*/
    /*               Seven - sounds, thinks             						*/
    /*__________>    Gypsy - activator, modified func_weather     	 <__________*/
    
    float SPAWN_RAIN = 1;
    float SPAWN_SNOW = 2;
    
    float CLEAR = 0;
    float FORECAST = 1;
    
    .float weather;
    
    /*===============================================
                         Sounds 
    ===============================================*/
    
    void() regenton = 
    {	if (random()> 0.94) 	// make rain sounds
    	{
    		precache_sound ("ambience/rain.wav");		
    		sound (self, CHAN_VOICE, "ambience/rain.wav", 1, ATTN_NORM); 
    	}		
    	else
    		return;
    };
    
    void() blitzton =  
    {	if (random()> 0.997)	// maybe it will thunder
    	{
    		precache_sound ("ambience/thunderrain.wav");	
    		sound (self, CHAN_WEAPON, "ambience/thunderrain.wav", 1, ATTN_NORM);
    	}
    	else
    		return;
    };
    
    /*===============================================
                         Thinks
    ===============================================*/
    
    void() snow_think =
    {	self.nextthink = time + 0.1;				//just keep thinking about yourself, and every time you do...
    	te_particlesnow(self.absmin, self.absmax, self.dest, self.count, self.cnt);		//...keep doing this (DP_EXTENSIONS)
    };
    
    void() rain_think =
    {	self.nextthink = time + 0.1;				//just keep thinking about yourself, and every time you do...
    	te_particlerain(self.absmin, self.absmax, self.dest, self.count, self.cnt);		//...keep doing this (DP_EXTENSIONS)
    	
    	blitzton();	//and this
    	regenton();	//and this
    };
    
    /*===============================================
                        Activator
    ===============================================*/
    
    void() weather_use =
    {	if(!self.weather || self.weather == CLEAR)		//if the weather is clear
    	{	self.weather = FORECAST;					//it's not anymore
    		if (self.spawnflags & SPAWN_RAIN)			//is it raining
    		{	precache_sound ("ambience/thunderrain.wav");
    			sound (self, CHAN_WEAPON, "ambience/thunderrain.wav", 1, ATTN_NORM);
    			self.think = rain_think;
    		}
    		else if (self.spawnflags & SPAWN_SNOW)		//or snowing
    		{	self.think = snow_think;
    		}
    		self.nextthink = time + 0.1;				//whatever it is, do it in a 10th of a second
    		return;										//stop this script here, before it can turn itself off (code below)
    	}
    	
    	//this applies to using triggers, as that is the only way this function could be called a second time
    	self.weather = CLEAR;							//if the weather isn't clear, the script will get this far and clear it up
    	self.think = SUB_Null;							//stop thinking about snow/rain
    };
    
    /*===============================================
                     Mother Nature
    ===============================================*/
    void() func_weather =
    {	//define self
    	self.angles = '0 0 0';		//probably unnecessary
    	self.velocity = '0 0 0';	//probably unnecessary
    	self.movetype = MOVETYPE_NONE;
    	self.solid = SOLID_NOT;
    	
    	//define the model
    	setmodel(self, self.model);
    	setorigin(self, self.origin);
    	setsize(self, self.mins, self.maxs);
    	self.model = ""; //????
    	
    	//correct missing flag error
    	if( !( self.spawnflags & SPAWN_RAIN ) && !( self.spawnflags & SPAWN_SNOW ) ) 	//if niether flag is set
    		self.spawnflags = self.spawnflags + ( self.spawnflags & SPAWN_RAIN );		//default to rain
    		
    	//set defaults if values are not already set
    	if ( (!self.dest) && ( self.spawnflags & SPAWN_RAIN ) )
    		self.dest = '0 0 -700';
    	else if ( (!self.dest) && ( self.spawnflags & SPAWN_SNOW ) )
    		self.dest = '0 0 -100';
    	
    	if (!self.cnt)
    		self.cnt = 12;
    		
    	if (!self.count)
    		self.count = ( self.absmax_x - self.absmin_x ) * ( self.absmax_y - self.absmin_y ) / 8192;
    	if (self.count < 1)
    	{	remove(self);
    		return;
    	}
    	
    	self.count = ceil(self.count * 0.1);  //adjust
    	
    	if(!self.targetname)			//if self cannot be targeted, turn on weather
    		weather_use();
    	else							//otherwise wait til a trigger has been tripped
    		self.use = weather_use;
    }
    Add to q1.game/id1/entities.ent
    Code:
    <group name="func_weather" color="0.5 0.0 0.5">
    	<targetname key="targetname" name="targetname">Triggering this name will turn the weather on/off. Including a targetname starts weather as off.</targetname>
    	Flags:
    	<flag key="SPAWN_RAIN" name="rain" bit="0">Spawns rain</flag>
    	<flag key="SPAWN_SNOW" name="snow" bit="1">Spawns snow</flag>
    	Keys:
    	<real3 key="dest" name="fall speed">fallspeed 0 0 -700 is default in the QC</real3>
    	<integer key="count" name="rain density">rain density</integer>
    	<integer key="cnt" name="color(0-255)">alpha to white by 15, higher numbers bring colors - 12 is default in the QC</integer>
    </group>
    EDIT: I just realized that targetname isn't doing anything in my ent definition. No targetname field is showing up in the radiant entity inspector. I copied and pasted that code from somewhere else in the ent when it was in its default state. In other words, there is no mistake, it simply does not work. This is slightly annoying at the worst. All you have to do is manually type "targetname" in the key field and "whateverNameYouWant" in the value field, within the radiant entity inspector, and then press enter. I guess you can also remove the <targetname> line from my .ent definition.
    Last edited by MadGypsy; 04-19-2013, 06:15 PM.
    http://www.nextgenquake.com
Working...
X