GS-Entbase: Initial func_pushable implementation
This commit is contained in:
parent
03b16ff905
commit
42960cda05
1 changed files with 88 additions and 9 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,7 +19,9 @@
|
|||
"target" Target when triggered.
|
||||
"killtarget" Target to kill when triggered.
|
||||
|
||||
STUB!
|
||||
This is essentially the same entity as a func_breakable, but
|
||||
a player can push and pull it around the level.
|
||||
It uses stepping player physics to move around.
|
||||
|
||||
Trivia:
|
||||
This entity was introduced in Half-Life (1998).
|
||||
|
@ -27,26 +29,103 @@ This entity was introduced in Half-Life (1998).
|
|||
|
||||
class func_pushable:func_breakable
|
||||
{
|
||||
entity m_pPuller;
|
||||
entity m_eCollBox;
|
||||
|
||||
void(void) func_pushable;
|
||||
|
||||
virtual void(void) customphysics;
|
||||
virtual void(void) touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) PlayerTouch;
|
||||
virtual void(void) OnPlayerUse;
|
||||
};
|
||||
|
||||
void
|
||||
func_pushable::customphysics(void)
|
||||
{
|
||||
tracebox(origin, mins, maxs, origin + (velocity * frametime), MOVE_NORMAL, this);
|
||||
input_movevalues = [0,0,0];
|
||||
input_impulse = 0;
|
||||
input_buttons = 0;
|
||||
input_angles = [0,0,0];
|
||||
input_timelength = frametime;
|
||||
|
||||
/* when we pull the box, it'll follow us whereever we go, just not too fast so it doesn't clip into us! */
|
||||
if (!m_pPuller.button5) {
|
||||
m_pPuller = world;
|
||||
} else {
|
||||
/* drag us, make sure we don't collide */
|
||||
velocity[0] = m_pPuller.velocity[0] * 0.9f;
|
||||
velocity[1] = m_pPuller.velocity[1] * 0.9f;
|
||||
}
|
||||
|
||||
/* see if we're clipping against entities or other func_pushable_bbox helper entities */
|
||||
vector position = absmin + (0.5 * (absmax - absmin));
|
||||
|
||||
/* if we're too far away from our box, split */
|
||||
if ((vlen(m_pPuller.origin - position) - vlen(size)) > 64)
|
||||
m_pPuller = world;
|
||||
|
||||
tracebox(position, -(size/2) * 0.95f, (size/2) * 0.95f, \
|
||||
position + (velocity * input_timelength), MOVE_NORMAL, this);
|
||||
|
||||
if (trace_fraction < 1.0f)
|
||||
return;
|
||||
|
||||
/* run the physics, then fix our helper bbox! */
|
||||
runstandardplayerphysics(this);
|
||||
setorigin(m_eCollBox, absmin + (0.5 * (absmax - absmin)));
|
||||
}
|
||||
|
||||
void
|
||||
func_pushable::touch(void)
|
||||
func_pushable::PlayerTouch(void)
|
||||
{
|
||||
if (other.movetype == MOVETYPE_WALK) {
|
||||
|
||||
/* don't cause bounces */
|
||||
if (other.movetype == MOVETYPE_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the real position of the pushable */
|
||||
vector position = absmin + (0.5 * (absmax - absmin));
|
||||
|
||||
/* check if we're inside the pushable */
|
||||
if (other.origin[0] >= absmin[0] && other.origin[0] <= absmax[0])
|
||||
if (other.origin[1] >= absmin[1] && other.origin[1] <= absmax[1])
|
||||
return;
|
||||
|
||||
/* check if we're above the pushable... */
|
||||
if ((other.absmin[2] + 16) >= absmax[2]) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the direction of the pushing player towards the pushable, then get a matrix */
|
||||
makevectors(vectoangles(other.origin - position));
|
||||
|
||||
/* add forward direction times speed */
|
||||
velocity = v_forward * -64;
|
||||
}
|
||||
|
||||
void
|
||||
func_pushable::OnPlayerUse(void)
|
||||
{
|
||||
m_pPuller = eActivator;
|
||||
}
|
||||
|
||||
void
|
||||
func_pushable::Respawn(void)
|
||||
{
|
||||
func_breakable::Respawn();
|
||||
movetype = MOVETYPE_STEP;
|
||||
touch = PlayerTouch;
|
||||
PlayerUse = OnPlayerUse;
|
||||
|
||||
if (!m_eCollBox) {
|
||||
m_eCollBox = spawn();
|
||||
m_eCollBox.classname = "func_pushable_bbox";
|
||||
m_eCollBox.solid = SOLID_BBOX;
|
||||
m_eCollBox.owner = this;
|
||||
setsize(m_eCollBox, -(size/2) * 0.9f, (size/2) * 0.9f);
|
||||
setorigin(m_eCollBox, absmin + (0.5 * (absmax - absmin)));
|
||||
}
|
||||
|
||||
velocity = other.velocity * 0.25;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue