quake-rerelease-qc/quakec_mg1/func_fade.qc
2022-04-06 14:43:08 -05:00

121 lines
3.3 KiB
C++

/* Copyright (C) 1996-2022 id Software LLC
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
const float FUNC_FADE_STATE_HIDDEN = 0;
const float FUNC_FADE_STATE_VISIBLE = 1;
const float FUNC_FADE_DISTANCE_MAXSPEED = 320;
float func_fade_get_shortest_playerdistance()
{
float dist = 32767;
float d;
vector vpos;
entity pl = find (world, classname, "player");
while (pl != world)
{
vpos = pl.origin + pl.view_ofs;
d = vlen(self.oldorigin - vpos);
if(d < dist) dist = d;
pl = find (pl, classname, "player");
}
return dist;
}
void func_fade_set_nextthink_for_distance(float dist)
{
self.nextthink = self.ltime + Clamp(dist / FUNC_FADE_DISTANCE_MAXSPEED, 0.05, 2.0);
}
void func_fade_set_alpha(float a, float force=FALSE)
{
a = Clamp(a, 0, 1);
if( !force && fabs(a - self.alpha) < 0.001) return;
if (self.state == FUNC_FADE_STATE_HIDDEN && a > 0)
{
self.state = FUNC_FADE_STATE_VISIBLE;
self.model = self.mdl;
}
else if (self.state == FUNC_FADE_STATE_VISIBLE && a == 0)
{
self.state = FUNC_FADE_STATE_HIDDEN;
self.model = string_null;
}
self.alpha = a;
}
void func_fade_think()
{
float dist = func_fade_get_shortest_playerdistance();
float diff = dist - self.distance;
if (diff < 0)
{
//Outside the transition zone, inside the circle
func_fade_set_alpha(1);
dist = -diff;
func_fade_set_nextthink_for_distance(dist);
}
else if(diff > self.lip)
{
//Outside the transition zone, outside the circle
func_fade_set_alpha(0);
dist = diff - self.lip;
func_fade_set_nextthink_for_distance(dist);
}
else
{
//In the transition zone
diff/= self.lip;
func_fade_set_alpha(1 - diff);
self.nextthink = self.ltime + 0.05;
}
}
void func_fade()
{
if(TRUE)
{
dprint("WARNING: A func_fade was spawned. This entity is obsolete, and was converted to a func_wall instead.\n")
func_wall();
return;
}
if(!self.distance) self.distance = 2048; //Radius of fade circle
if(!self.lip) self.lip = 256; // Lip around fade circle
self.waitmax = self.distance + self.lip;
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_PUSH;
setmodel(self, self.model);
self.mdl = self.model;
self.oldorigin = self.mins + ((self.maxs - self.mins) * 0.5);
self.state = FUNC_FADE_STATE_VISIBLE;
self.think = func_fade_think;
self.nextthink = self.ltime + 0.2 + random() * 0.2;
func_fade_set_alpha(0, TRUE);
}