Found in hip_push.qc. A search of hipnotic map .bsp found none in use.
The QUAKED entry has this:
Hipnotic note: Not quite working, but fun to play around with.
I decided to put one on my test map.
How it works: make a map brush with texture, etc. Select it then make
it a func_pushable. (In radiant the right-click menu brings up entity options.)
Issues I noted:
- Odd shapes not handled - bounding box is rectalinear. Does not conform to bsp brush shape or rotates.
- Only touch map brush on bottom - you must use func_illusionary walls for sides and top
- if sides or top touch a solid map brush, the pushable will fall out of the level when spawned
Then I decided to improve the code:
// allow new ents to pass back pointer to calling fn
entity nspawn;
.vector v__;
/*QUAKED func_pushable (0 .5 .8) ? MDL LOC
-------- HIPN --------
Hipnotic Miscellaneous Geometry
-------------------------------
"MDL" using a custom bps or mdl model on pushable or target
(doesnt work on pushable, makes little sense on target ent)
"LOC" locate pushable proxy to target ent
"view_ofs" - z adust for LOC locate ent that ends up in floor '0 0 1' suggested
"target" - spawn a 'push wall proxy' for this ent and enable it as a pushable
(you can make an explodbox pushable this way - then it wont blow up
unless splash damaged)
"targetname" - allow pushable to be targeted for removal
Pushable walls.
Can NOT be bounded on top or sides by a solid brush.
If you want a pushable hidden in a wall it MUST have a few
units of func_illusionary around it. Suggest 4 qu. brush.
Hipnotic note: Not quite working,
but fun to play around with.
*/
/* Pushable walls QuickC program
By Jim Dose' 9/16/96
Copyright (c)1996 Hipnotic Interactive, Inc.
All rights reserved.
Distributed (unsupported) on 3.12.97
*/
void() push_use =
{
// local vector delta;
// local float x;
// local float y;
// walkmove (other.angles_y, 16 * frametime);
/*
if ( (other.angles_y >= 315) || (other.angles_y < 45))
{
walkmove ( 0, 16 * frametime);
}
else if ( (other.angles_y >= 45) && (other.angles_y < 135))
{
walkmove ( 90, 16 * frametime);
}
else if ( (other.angles_y >= 135) && (other.angles_y < 225))
{
walkmove ( 180, 16 * frametime);
}
else if ( (other.angles_y >= 225) && (other.angles_y < 315))
{
walkmove ( 270, 16 * frametime);
}
else
{
return;
}
*/
// fallout fix - and fails
self.movetype = MOVETYPE_STEP;
self.owner.movetype = MOVETYPE_PUSH;
makevectors(other.angles);
// x = fabs( v_forward_x );
// y = fabs( v_forward_y );
self.v___x = fabs( other.velocity_x );
self.v___y = fabs( other.velocity_y );
#ifndef nodprint
dprint( ftos( self.v___x ) );
dprint( ", " );
dprint( ftos( self.v___y ) );
#endifdef
if ( self.v___x > self.v___y )
{
#ifndef nodprint
dprint( " x move\n\n\n\n" );
#endifdef
if ( other.velocity_x > 0 )
{
walkmove ( 0, 16 * frametime);
}
else
{
walkmove( 180, 16 * frametime );
}
}
else
{
#ifndef nodprint
dprint( " y move\n\n\n\n" );
#endifdef
if ( other.velocity_y > 0 )
{
walkmove ( 90, 16 * frametime);
}
else
{
walkmove( 270, 16 * frametime );
}
}
// this makes blocks un-pushable
// and some blocks still went thru floor, just slower
// self.velocity_z = 0;
// self.owner.velocity_z = 0;
// delta = self.origin - self.oldorigin;
setorigin (self.owner, self.owner.oldorigin + (self.origin - self.oldorigin) + self.view_ofs ); //delta );
};
/*QUAKED func_pushable (0 .5 .8) ?
Pushable walls.
*/
// something wrong where these fall from the level
// initial MOVETYPE_NONE fixes this, but still fsck on ops with these
// fall from level is a result of bottom of proxy being embedded in floor
void() func_pushable =
{
// local entity new;
// local vector newsize;
if (self.target != "")
{
if (time < 3) // cant find target before it spawns
{
self.think = func_pushable;
self.nextthink = time + 2;
return;
}
nspawn = self;
self = find (world, targetname, nspawn.target);
if (!self) return; // reload may correct this asp
self.solid = SOLID_BSP;
self.movetype = MOVETYPE_NONE;
self.oldorigin = self.origin;
self.targetname = nspawn.targetname; // in case of a remove target on pushable
// nspawn.origin = self.origin; // does not relocate pushable
}
else
{
self.mangle = self.angles;
self.angles = '0 0 0';
self.classname = "pushablewall";
self.solid = SOLID_BSP;
// self.movetype = MOVETYPE_PUSH;
self.movetype = MOVETYPE_NONE;
setmodel (self, self.model);
setorigin( self, self.origin );
setsize (self, self.mins, self.maxs );
self.oldorigin = self.origin;
nspawn = spawn();
nspawn.targetname = self.targetname; // in case pushable is targeted
}
nspawn.owner = self;
nspawn.mangle = self.mangle;
nspawn.angles = self.angles;
nspawn.classname = "pushablewallproxy";
nspawn.solid = SOLID_BBOX;
// nspawn.movetype = MOVETYPE_STEP;
nspawn.movetype = MOVETYPE_NONE;
nspawn.origin = ( self.mins + self.maxs ) * 0.5 + '0 0 1';
self.v__ = ( self.maxs - self.mins ) * 0.5;
nspawn.mins = '-1 -1 0' - self.v__ + nspawn.view_ofs;
nspawn.maxs = '1 1 -2' + self.v__;
if (nspawn.spawnflags & 1) setmodel (self, self.mdl); // _only_ works with target ent! - a pure pushable MUST use the map brush supplied
if (nspawn.spawnflags & 2)
{
nspawn.origin = self.origin;
nspawn.maxs = self.maxs + '1 1 -2';
nspawn.mins = '-1 -1 0' + self.mins + nspawn.view_ofs;
}
setsize( nspawn, nspawn.mins, nspawn.maxs );
setorigin( nspawn, nspawn.origin );
nspawn.oldorigin = nspawn.origin;
nspawn.touch = push_use;
};
So, what does the "target" improvement do?
You can push misc_explobox or other miscellaneous model items.
Issues still exist. Some tricks would need to be implemented to pass damage on to a shootable item
like misc_explobox. Likewise for a touchable item.
Other ideas I have:
- implement the damage pass-through
- remove players viswep while pushing
- see if it works with SOLID_BSP for shape conform
Video of pushable in action: Moddb.com
This uses the "LOC" flag and target pointer to a regular misc_explobox.
The misc_explobox has the corresponding targetname:
// entity 1374
{
"view_ofs" "0 0 1"
"spawnflags" "2"
"target" "pushqbomb"
"origin" "1224 -376 0"
"classname" "func_pushable"
// brush 0
{
( -179 -2712 0 ) ( -218 -2672 0 ) ( -264 -2718 0 ) chaos/pipe1c 80 0 0 0.500000 0.500000 0 0 0
( -239 -2735 64 ) ( -193 -2689 64 ) ( -154 -2729 64 ) chaos/pipe1c 80 0 0 0.500000 0.500000 0 0 0
( -232 -2696 0 ) ( -208 -2696 0 ) ( -232 -2696 64 ) chaos/pipe1c 80 0 0 0.500000 0.500000 0 0 0
( -208 -2696 0 ) ( -208 -2712 0 ) ( -208 -2696 64 ) chaos/pipe1c 64 0 0 0.500000 0.500000 0 0 0
( -216 -2728 0 ) ( -224 -2728 0 ) ( -216 -2728 64 ) chaos/pipe1c 80 0 0 0.500000 0.500000 0 0 0
( -240 -2728 0 ) ( -240 -2712 0 ) ( -240 -2728 64 ) chaos/pipe1c 64 0 0 0.500000 0.500000 0 0 0
}
}
// entity 1375
{
"origin" "-256 -2688 0"
"classname" "misc_explobox"
"targetname" "pushqbomb"
}
Addendum - add a push "scraping" sound
Edited by: numbersix