djcev.com

//

Git Repos / fte_dogmode / qc / func / fall2.qc

Last update to this file was on 2024-04-12 at 18:56.

Show fall2.qc

//==============================================================================
// func_fall2 -- code attributed to RennyC & whirledtsar
//==============================================================================

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

const float FALL2_PLAYER_TRIGGERED = 1;
const float FALL2_MONSTER_TRIGGERED = 2;
const float FALL2_BREAKABLE = 8; // VR
// const float FALL2_SOLID = 16; // VR

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

// temp_fall2_field
void() temp_fall2_field_touch;
entity(entity own, vector nmins, vector nmaxs) spawn_temp_fall2_field;
void(entity e) temp_fall2_field_init;
strip void() temp_fall2_field;

// func_fall2
void() func_fall2_think;
void() func_fall2_touch;
void() func_fall2_use;
void(entity e) func_fall2_breakable_fields;
void(entity e) func_fall2_init;
void() func_fall2;

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

//----------------------------------------------------------------------
// class temp_fall2_field: base_tempentity
// {
//--------------------------------------------------------------
void() temp_fall2_field_touch =
{
if (other.flags & FL_FLY)
// flying monsters shouldn't trigger falling platforms
return;

if (other.flags & FL_MONSTER)
{
if (!self.owner)
{
dprint ("temp_fall2_field_touch: no owner!\n");
remove (self);
return;
}

self.owner.think = func_fall2_use;
self.owner.nextthink = self.owner.ltime + 0.1;
remove (self);
}
};

//--------------------------------------------------------------
entity(entity own, vector nmins, vector nmaxs) spawn_temp_fall2_field =
{
local entity e = spawn ();
e.owner = own;
setsize (e, nmins, nmaxs);
setorigin (e, own.origin);
setmodel (e, own.model);
temp_fall2_field_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) temp_fall2_field_init =
{
e.classname = "temp_fall2_field";
e.classtype = CT_TEMP_FALL2_HELPER;
base_tempentity_init (e);
e.solid = SOLID_TRIGGER;
e.touch = temp_fall2_field_touch;
};

//--------------------------------------------------------------
strip void() temp_fall2_field =
{
temp_fall2_field_init (self);
};
// };

/*QUAKED func_fall2 (0 .5 .8) ? X X X X X 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
Falling brush by RennyC with additions from whirledtsar

wait - how long until the brush begins falling
noise - the sound to make when touched / activated
noise2 - the sound to make before it's removed, pain_finished of -1 disables noise2 as the object stays forever
cnt - 0 is default behavior (MOVETYPE_TOSS), 1 means collisions are disabled while falling (MOVETYPE_NOCLIP), 2 turns the brush into a bouncing entity (MOVETYPE_BOUNCE)
pain_finished - default of 0.01, higher value has the object/brush fade out faster thus in turn affecting how long it stays. -1 stays forever
speed - speed as to how fast something falls per game frame, default is 10, higher values mean faster falling. Only for cnt of 1 (MOVETYPE_NOCLIP).
Recommended to use lip for max fall speed on MOVETYPE_TOSS/BOUNCE entities (cnt 0 and 2) as they follow Quake's default gravity
lip - maximum fall speed that can be achieved, caps 'speed' variable. Default is -800
avelocity - have it spin when activated using X, Y, Z vector coordinates. MOVETYPE_BOUNCE ignores avelocity !Use an origin brush for proper spin!

spawnflags:
Default behavior allows anyone to activate func_fall2 on touch ONLY
1 - Player activated only
2 - Monster activated only
8 - break on impact (use style key for textures, see manual for more)
16 - fall solid; remains solid on ground

Able to .target other entities, including other func_fall2s
*/
//----------------------------------------------------------------------
// class func_fall2: base_breakable
// {
//--------------------------------------------------------------
void() func_fall2_think =
{
// turn off quake engine splash sound
self.waterlevel = self.watertype = 0;

if (self.attack_finished < time)
{
if (self.target != __NULL__ && self.target != "")
sub_useandforgettargets ();


// removed FALL_SOLID behavior -- dumptruck_ds
self.solid = SOLID_NOT;

if (self.pos1 != '0 0 0')
// apply stored avelocity vector values
self.avelocity = self.pos1;

if (self.pos2 && !self.velocity)
// Add velocity movement
self.velocity = self.pos2;

if (self.cnt > 0)
{
// cnt over 0
if (self.cnt >= 2)
{
self.movetype = MOVETYPE_BOUNCE;
if (self.velocity_z < self.lip)
self.velocity_z = self.lip;
}
else
{
// cnt is 1
self.movetype = MOVETYPE_NOCLIP;
if (self.velocity_z > self.lip)
self.velocity_z -= self.speed *
(frametime * 100);
else
self.velocity_z = self.lip;
}
}
else
{
// default behavior (cnt is 0)
self.movetype = MOVETYPE_TOSS;
if (self.velocity_z < self.lip)
self.velocity_z = self.lip;
}

if (self.pain_finished != -1)
{
if (self.alpha > 0.1)
self.alpha -= self.pain_finished;
else
{
if (self.noise2 != __NULL__ &&
self.noise2 != "")
{
sound (self, CHAN_AUTO,
self.noise2,
1, ATTN_NORM);
}
remove (self);
return;
}
}

if (self.flags & FL_ONGROUND &&
self.spawnflags & FALL2_BREAKABLE)
{
// VR
// aka BREAKABLE_NO_MONSTERS
self.spawnflags(-)1;
// aka BREAK_EXPLODE
self.spawnflags(-)2;
// because of how debris origin is calculated
self.mins = self.absmin;
self.maxs = self.absmax;
// debris gets velocity from health
self.health = self.lip * 0.1;
// func_breakable uses cnt for quantity of
// debris to spawn
self.cnt = self.count;
// removes self
base_breakable_die ('0 0 0');
return;
}
}

self.nextthink = self.ltime + 0.1;
};

//--------------------------------------------------------------
void() func_fall2_touch =
{
if (!other.takedamage)
return;

if (other.classtype != CT_PLAYER)
// player activated only
return;

if (self.spawnflags & FALL2_MONSTER_TRIGGERED)
// disable on monster only, also fixes weird issue
return;

self.think = func_fall2_think;
self.nextthink = self.ltime + 0.1;
self.attack_finished = time + self.wait;

// if (self.spawnflags & FALL_SOLID)
// {
// // VR
// setsize (self, self.mins, self.maxs);
// self.solid = SOLID_BBOX;
// }
// else
// {
// self.solid = SOLID_NOT;
// }

if (self.noise != __NULL__ && self.noise != "")
sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);

// disable touch, only do self once!
self.touch = sub_null;

if (self.trigger_field)
remove (self.trigger_field);
};

//--------------------------------------------------------------
void() func_fall2_use =
{
self.think = func_fall2_think;
self.nextthink = self.ltime + 0.1;
// disable touch when used
self.touch = sub_null;

// if (self.spawnflags & FALL_SOLID)
// {
// // VR
// setsize (self, self.mins, self.maxs);
// self.solid = SOLID_BBOX;
// }
// else
// {
// self.solid = SOLID_NOT;
// }

self.attack_finished = time + self.wait;
if (self.noise != __NULL__ && self.noise != "")
sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
};

// You may have to modify your multi_touch(); command in triggers.qc
// to allow both monsters & players to activate trigger_once/multiple.
// I recommend allowing the mapper themselves to select how that
// occurs. Default behavior is player only.

//--------------------------------------------------------------
void(entity e) func_fall2_breakable_fields =
{
base_breakable_template_setup (e);

e.mdl_debris = "progs/debris.mdl";
precache_model (e.mdl_debris);

if (e.noise1 != "")
precache_sound (e.noise1);

// adding new default sounds for "simple" breakables in 1.2.0
// -- dumptruck_ds

// here's generic metal breaking
if (e.style == 0 || e.style == 11 ||
e.style == 12 || e.style == 17 ||
e.style == 18 || e.style == 19 ||
e.style == 24 || e.style == 31)
{
if !(e.noise1)
{
precache_sound ("break/metal2.wav");
e.noise1 = "break/metal2.wav";
}
}

if (e.style == 3 || e.style == 4 || e.style == 5)
{
if !(e.noise1)
{
precache_sound ("break/wood1.wav");
precache_sound ("break/wood2.wav");
// wood only randomized
if (random() > 0.6)
e.noise1 = "break/wood1.wav";
else
e.noise1 = "break/wood2.wav";
}
}

// glass sounds -- e is more of a shattering sound anyway
if (e.style == 6 || e.style == 7 || e.style == 8 ||
e.style == 9 || e.style == 10)
{
if !(e.noise1)
{
precache_sound ("break/metal1.wav");
e.noise1 = "break/metal1.wav";
}
}

if (e.style == 1 || e.style == 2 ||
e.style == 13 || e.style == 14 ||
e.style == 15 || e.style == 16 ||
e.style == 20 || e.style == 21 ||
e.style == 22 || e.style == 23)
{
if !(e.noise1)
{
precache_sound ("break/bricks1.wav");
e.noise1 = "break/bricks1.wav";
}
}

if (e.style == 25 || e.style == 26 ||
e.style == 27 || e.style == 28 ||
e.style == 29 || e.style == 30)
{
if !(e.noise1)
{
precache_sound ("break/stones1.wav");
e.noise1 = "break/stones1.wav";
}
}

if (!e.health)
e.health = 20;
if (!e.count)
// was 6 dumptruck_ds
e.count = 5;
};

//--------------------------------------------------------------
void(entity e) func_fall2_init =
{
e.classname = "func_fall2";
e.classtype = CT_FUNC_FALL2;
base_breakable_init (e);

// This is a hack to have monsters be able to trigger it
// by fake touch - Thanks to Nahuel

// Don't spawn on player only or if I'm a targetable
if (!(e.spawnflags & FALL2_PLAYER_TRIGGERED) &&
!(e.targetname))
{
// Link 'em -- modified to use a helper class -- CEV
e.trigger_field = spawn_temp_fall2_field (e,
e.absmin, e.absmax + '0 0 8');
}

if (e.noise != __NULL__ && e.noise != "")
precache_sound (e.noise);
if (e.noise2 != __NULL__ && e.noise2 != "")
precache_sound (e.noise2);

e.alpha = 1.0;
e.solid = SOLID_BSP;
e.movetype = MOVETYPE_PUSH;

if (!e.pain_finished)
e.pain_finished = 0.01;

if (!e.targetname)
// .touch in this instance is for players only
e.touch = func_fall2_touch;

if (!e.speed)
e.speed = 10;
if (!e.lip)
e.lip = -800;

if (e.avelocity != '0 0 0')
{
// store it
e.pos1 = e.avelocity;
e.avelocity = '0 0 0';
}

if (e.spawnflags & FALL2_BREAKABLE)
{
// VR
// dont fade if set to break
e.pain_finished = -1;
func_fall2_breakable_fields (e);
}

e.use = func_fall2_use;
setmodel (e, e.model);
};

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

func_fall2_init (self);
};
// };

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

Log fall2.qc

Date Commit Message Author + -
2024-04-12 Moveable gibs, heads, some bugfixes cev +1 -1
2024-03-24 2nd pass refactor, rework QC class structure cev +213 -198
2024-02-18 Client/player, projectiles, entrypoints refactor cev +4 -3
2024-01-31 Class based monster refactor & start projectiles cev +27 -3
2024-01-09 Continue OO / Class-based refactor cev +320 -296
2023-11-27 Code reorg, minor movement changes, misc cev +362  

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