djcev.com

//

Git Repos / fte_dogmode / qc / func / door_secret.qc

Last update to this file was on 2024-06-15 at 19:50.

Show door_secret.qc

//==============================================================================
// func_door_secret -- SECRET DOORS
//==============================================================================

//======================================================================
// constants
//======================================================================

#ifdef SSQC
const float SECRET_OPEN_ONCE = 1; // stays open
const float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
const float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
const float SECRET_NO_SHOOT = 8; // only opened by trigger
const float SECRET_YES_SHOOT = 16; // shootable even if targeted
#endif

//======================================================================
// forward declarations
//======================================================================

// func_door_secret
#ifdef SSQC
void() func_door_secret_blocked;
void(entity attacker, float damage) func_door_secret_pain;
void(vector dir) func_door_secret_destroy;
void() func_door_secret_think;
void() func_door_secret_touch;
void() func_door_secret_use;
void(entity e) func_door_secret_init;
void() func_door_secret;
#endif

//------------------------------------------------------------------------------

/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

Basic secret door. Slides back, then to the side. Angle determines direction.
wait = # of seconds before coming back
1st_left = 1st move is left of arrow
1st_down = 1st move is down from arrow
always_shoot = even if targeted, keep shootable
t_width = override WIDTH to move back (or height if going down)
t_length = override LENGTH to move sideways
"dmg" damage to inflict when blocked (2 default)

If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
"sounds"
1) medieval
2) metal
3) base
*/
//----------------------------------------------------------------------
// class func_door_secret: base_func
// {
#ifdef SSQC
//--------------------------------------------------------------
void() func_door_secret_blocked =
{
// handle projectiles blockers -- CEV
if (other.classgroup & CG_PROJECTILE)
if (other.mins != '0 0 0' || other.maxs != '0 0 0')
setsize (other, '0 0 0', '0 0 0');

if (time < self.attack_finished)
return;

self.attack_finished = time + 0.5;
t_damage2 (other, self, self, self.dmg);
};

//--------------------------------------------------------------
void(entity attacker, float damage) func_door_secret_pain =
{
if (self.takedamage == DAMAGE_YES)
func_door_secret_use ();
};

//--------------------------------------------------------------
void(vector dir) func_door_secret_destroy =
{
if (self.takedamage == DAMAGE_YES)
func_door_secret_use ();
};

//--------------------------------------------------------------
void() func_door_secret_think =
{
switch (self.state)
{
case 1:
// fd_secret_move1: Wait after first movement
self.nextthink = self.ltime + 1.0;
sound (self, CHAN_VOICE, self.noise3,
VOL_MHI, ATTN_NORM);
break;
case 2:
// fd_secret_move2: move sideways w/sound
sound (self, CHAN_VOICE, self.noise2,
VOL_MHI, ATTN_NORM);
sub_calcmove (self, self.pos2, self.speed,
func_door_secret_think);
break;
case 3:
// fd_secret_move3: wait until time to go back
sound (self, CHAN_VOICE, self.noise3,
VOL_MHI, ATTN_NORM);
if (!(self.spawnflags & SECRET_OPEN_ONCE))
self.nextthink = self.ltime + self.wait;
break;
case 4:
// fd_secret_move4: move backward...
sound (self, CHAN_VOICE, self.noise2,
VOL_MHI, ATTN_NORM);
sub_calcmove (self, self.pos1, self.speed,
func_door_secret_think);
break;
case 5:
// fd_secret_move5: wait 1 second...
self.nextthink = self.ltime + 1.0;
sound (self, CHAN_VOICE, self.noise3,
VOL_MHI, ATTN_NORM);
break;
case 6:
// fd_secret_move6
sound (self, CHAN_VOICE, self.noise2,
VOL_MHI, ATTN_NORM);
sub_calcmove (self, self.oldorigin, self.speed,
func_door_secret_think);
break;
case 7:
// fd_secret_done
if (!self.targetname ||
self.spawnflags & SECRET_YES_SHOOT)
{
self.health = 10000;
self.takedamage = DAMAGE_YES;
self.destroy = func_door_secret_destroy;
self.th_pain = func_door_secret_pain;
// self.th_pain = sub_nullpain;
}

sound (self, CHAN_VOICE, self.noise3,
VOL_MHI, ATTN_NORM);
break;
default:
dprint (sprintf("func_door_secret_think: "
"unhandled state %f!\n",
self.state));
}

if (self.state < 4 ||
!(self.spawnflags & SECRET_OPEN_ONCE))
{
self.state++;
}
};

//--------------------------------------------------------------
// secret_touch - ouch; Prints messages
//--------------------------------------------------------------
void() func_door_secret_touch =
{
// from Copper -- dumptruck_ds
if (sub_checkvalidtouch(other) == FALSE)
return;

if (self.attack_finished > time)
return;

self.attack_finished = time + 2;

if (self.message != "")
{
centerprint (other, self.message);
sound (other, CHAN_BODY, "misc/talk.wav",
VOL_HIGH, ATTN_NORM);
}
};

//--------------------------------------------------------------
void() func_door_secret_use =
{
local float temp;

self.health = 10000;

// exit if still moving around...
if (self.origin != self.oldorigin)
return;

// no more message
self.message = __NULL__;

// fire all targets / killtargets
sub_usetargets ();

if (!(self.spawnflags & SECRET_NO_SHOOT))
{
self.th_pain = sub_nullpain;
self.takedamage = DAMAGE_NO;
}

self.velocity = '0 0 0';

// Make a sound, wait a little...
sound (self, CHAN_VOICE, self.noise1, VOL_MHI, ATTN_NORM);
self.nextthink = self.ltime + 0.1;

// 1 or -1
temp = 1 - (self.spawnflags & SECRET_1ST_LEFT);
makevectors (self.mangle);

if (!self.t_width)
{
if (self.spawnflags & SECRET_1ST_DOWN)
self.t_width = fabs (v_up * self.size);
else
self.t_width = fabs (v_right * self.size);
}

if (!self.t_length)
self.t_length = fabs (v_forward * self.size);

if (self.spawnflags & SECRET_1ST_DOWN)
self.pos1 = self.origin - v_up * self.t_width;
else
self.pos1 = self.origin + v_right *
(self.t_width * temp);

self.pos2 = self.pos1 + v_forward * self.t_length;
self.state = 1;
sub_calcmove (self, self.pos1, self.speed,
func_door_secret_think);
sound (self, CHAN_VOICE, self.noise2, VOL_MHI, ATTN_NORM);
};

//--------------------------------------------------------------
void(entity e) func_door_secret_init =
{
e.classname = "func_door_secret";
e.classtype = CT_FUNC_DOOR_SECRET;
base_func_init (e);

if (e.sounds == 0)
e.sounds = 3;

if (e.sounds == 1)
{
precache_sound ("doors/latch2.wav");
precache_sound ("doors/winch2.wav");
precache_sound ("doors/drclos4.wav");
e.noise1 = "doors/latch2.wav";
e.noise2 = "doors/winch2.wav";
e.noise3 = "doors/drclos4.wav";
}

if (e.sounds == 2)
{
precache_sound ("doors/airdoor1.wav");
precache_sound ("doors/airdoor2.wav");
e.noise2 = "doors/airdoor1.wav";
e.noise1 = "doors/airdoor2.wav";
e.noise3 = "doors/airdoor2.wav";
}

if (e.sounds == 3)
{
precache_sound ("doors/basesec1.wav");
precache_sound ("doors/basesec2.wav");
e.noise2 = "doors/basesec1.wav";
e.noise1 = "doors/basesec2.wav";
e.noise3 = "doors/basesec2.wav";
}

if (!e.dmg)
e.dmg = 2;

// Magic formula...
e.speed = 50;
e.mangle = e.angles;
e.angles = '0 0 0';
e.solid = SOLID_BSP;
e.movetype = MOVETYPE_PUSH;
setmodel (e, e.model);
setorigin (e, e.origin);

e.blocked = func_door_secret_blocked;
e.think = func_door_secret_think;
e.touch = func_door_secret_touch;
e.use = func_door_secret_use;

if (!e.targetname || e.spawnflags & SECRET_YES_SHOOT)
{
e.health = 10000;
e.takedamage = DAMAGE_YES;
e.th_pain = func_door_secret_pain;
e.destroy = func_door_secret_destroy;
}

e.oldorigin = e.origin;

if (!e.wait)
// 5 seconds before closing
e.wait = 5;
};

//--------------------------------------------------------------
void() func_door_secret =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

func_door_secret_init (self);
};
#endif
// };

Return to the top of this page or return to the overview of this repo.

Log door_secret.qc

Return to the top of this page or return to the overview of this repo.