trigger_camera: Misc improvements, plus added test map.

This commit is contained in:
Marco Cawthorne 2020-11-28 22:52:56 +01:00
parent e0f5124cce
commit 1d02dccbb5
10 changed files with 425 additions and 97 deletions

Binary file not shown.

View File

@ -0,0 +1,138 @@
// entity 0
{
"classname" "worldspawn"
// brush 0
{
( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) next/cracked1 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) next/cracked1 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 256 192 8 ) ( 256 192 0 ) ( 256 -192 8 ) next/cracked1 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) next/cracked1 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) next/cracked1 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -256 -192 0 ) ( -256 192 0 ) ( -256 -192 8 ) next/cracked1 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
// brush 1
{
( 248 192 192 ) ( 248 -192 192 ) ( -264 192 192 ) skies/yukongold [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 256 192 264 ) ( -256 192 264 ) ( 256 192 256 ) skies/yukongold [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 256 192 264 ) ( 256 192 256 ) ( 256 -192 264 ) skies/yukongold [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -256 -192 128 ) ( 256 -192 128 ) ( -256 192 128 ) skies/yukongold [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( -256 -192 256 ) ( -256 -192 264 ) ( 256 -192 256 ) skies/yukongold [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -256 -192 256 ) ( -256 192 256 ) ( -256 -192 264 ) skies/yukongold [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
// brush 2
{
( 184 192 192 ) ( 184 -192 192 ) ( -328 192 192 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 192 192 264 ) ( -320 192 264 ) ( 192 192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -256 192 8 ) ( -256 192 0 ) ( -256 -192 8 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -768 -192 -128 ) ( -256 -192 -128 ) ( -768 192 -128 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( -320 -192 256 ) ( -320 -192 264 ) ( 192 -192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 -192 256 ) ( -320 192 256 ) ( -320 -192 264 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
// brush 3
{
( 760 192 192 ) ( 760 -192 192 ) ( 248 192 192 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 768 192 264 ) ( 256 192 264 ) ( 768 192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 192 8 ) ( 320 192 0 ) ( 320 -192 8 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -192 -192 -128 ) ( 320 -192 -128 ) ( -192 192 -128 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 256 -192 256 ) ( 256 -192 264 ) ( 768 -192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 256 -192 256 ) ( 256 192 256 ) ( 256 -192 264 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
// brush 4
{
( 184 -192 192 ) ( 184 -576 192 ) ( -328 -192 192 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 192 -192 264 ) ( -320 -192 264 ) ( 192 -192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 96 8 ) ( 320 96 0 ) ( 320 -288 8 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -768 -576 -128 ) ( -256 -576 -128 ) ( -768 -192 -128 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 272 -256 256 ) ( 272 -256 264 ) ( 784 -256 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 -576 256 ) ( -320 -192 256 ) ( -320 -576 264 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
// brush 5
{
( 184 256 192 ) ( 184 -128 192 ) ( -328 256 192 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 192 256 264 ) ( -320 256 264 ) ( 192 256 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 320 544 8 ) ( 320 544 0 ) ( 320 160 8 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -768 -128 -128 ) ( -256 -128 -128 ) ( -768 256 -128 ) next/bunker2 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0
( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) next/bunker2 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) next/bunker2 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
}
// entity 1
{
"classname" "info_player_start"
}
// entity 2
{
"classname" "info_player_deathmatch"
}
// entity 3
{
"classname" "light"
"origin" "128.000000 0.000000 64.000000"
"light" "100"
}
// entity 4
{
"classname" "light"
"origin" "-128.000000 0.000000 64.000000"
"light" "100"
}
// entity 5
{
"classname" "trigger_camera"
"target" "aimatme"
"moveto" "firststop"
"origin" "0.000000 -64.000000 0.000000"
"targetname" "mycamera"
}
// entity 6
{
"classname" "path_corner"
"origin" "-128.000000 -64.000000 0.000000"
"targetname" "firststop"
"target" "secondstop"
"message" "explo_first"
}
// entity 7
{
"classname" "path_corner"
"origin" "128.000000 -64.000000 0.000000"
"targetname" "secondstop"
"message" "explo_second"
}
// entity 6
{
"classname" "env_explosion"
"origin" "-128.000000 -64.000000 0.000000"
"targetname" "explo_first"
"spawnflags" "2"
}
// entity 7
{
"classname" "env_explosion"
"origin" "128.000000 -64.000000 0.000000"
"targetname" "explo_second"
"spawnflags" "2"
}
// entity 8
{
"classname" "info_notnull"
"origin" "0.000000 64.000000 0.000000"
"targetname" "aimatme"
}
// entity 9
{
"classname" "func_button"
"target" "mycamera"
// brush 0
{
( 8 48 8 ) ( 8 32 8 ) ( -8 48 8 ) measure/wall32 [ 1 0 0 16 ] [ -0 -1 -0 16 ] -0 0.5 0.5 0 0 0
( 8 48 8 ) ( -8 48 8 ) ( 8 48 0 ) measure/wall32 [ 1 0 0 16 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( 8 48 8 ) ( 8 48 0 ) ( 8 32 8 ) measure/wall32 [ 0 1 0 48 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -8 32 -8 ) ( 8 32 -8 ) ( -8 48 -8 ) measure/wall32 [ 1 0 0 16 ] [ -0 -1 -0 16 ] -0 0.5 0.5 0 0 0
( -8 32 0 ) ( -8 32 8 ) ( 8 32 0 ) measure/wall32 [ 1 0 0 16 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
( -8 32 0 ) ( -8 48 0 ) ( -8 32 8 ) measure/wall32 [ 0 1 0 48 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0
}
}

View File

@ -251,19 +251,7 @@ CSQC_UpdateView(float w, float h, float focus)
addentities(MASK_ENGINE);
if (pSeat->m_flCameraTime > time) {
vector lastang;
float lerp;
lerp = bound(0.0f, 1.0f - clframetime, 1.0f);
makevectors(view_angles);
lastang = v_forward;
makevectors(pSeat->m_vecCameraAngle);
lastang[0] = Math_Lerp(lastang[0], v_forward[0], clframetime);
lastang[1] = Math_Lerp(lastang[1], v_forward[1], clframetime);
lastang[2] = Math_Lerp(lastang[2], v_forward[2], clframetime);
view_angles = vectoangles(lastang);
view_angles = pSeat->m_vecCameraAngle;
setproperty(VF_ORIGIN, pSeat->m_vecCameraOrigin);
setproperty(VF_CL_VIEWANGLES, view_angles);
setproperty(VF_ANGLES, view_angles);
@ -847,6 +835,13 @@ CSQC_Ent_Update(float new)
case ENT_AMBIENTSOUND:
Sound_ParseLoopingEntity(self, new);
break;
case ENT_OLDCAMERA:
trigger_camera tc = (trigger_camera)self;
if (new) {
spawnfunc_trigger_camera();
}
tc.ReceiveEntity(readfloat());
break;
case ENT_DLIGHT:
light_dynamic dl = (light_dynamic)self;
if (new) {

View File

@ -72,7 +72,6 @@ server/target_cdaudio.cpp
server/trigger_auto.cpp
server/trigger_autosave.cpp
server/trigger_cdaudio.cpp
server/trigger_camera.cpp
server/trigger_counter.cpp
server/trigger_hurt.cpp
server/trigger_changelevel.cpp

View File

@ -234,10 +234,8 @@ func_button::Trigger(entity act, int state)
MoveAway();
if (m_strOnPressed)
UseOutput(act, m_strOnPressed);
else
UseTargets(act, TRIG_TOGGLE, m_flDelay);
UseOutput(act, m_strOnPressed);
UseTargets(act, TRIG_TOGGLE, m_flDelay);
}
void

View File

@ -66,7 +66,7 @@ path_corner::Trigger(entity act, int state)
{
entity a;
if ((spawnflags & PC_FIREONCE) && (m_iFired)) {
if ((spawnflags & PC_FIREONCE) && m_iFired) {
return;
}
@ -114,5 +114,6 @@ void
path_corner::path_corner(void)
{
m_flWait = 1.0f;
m_flSpeed = 100.0f;
CBaseTrigger::CBaseTrigger();
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (c) 2016-2020 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
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED trigger_camera (1 0 0) (-8 -8 -8) (8 8 8)
"targetname" Name
"angles" Sets the pitch, yaw and roll angles of the camera
"target" Which entity we're aiming at. Overrides angles.
"wait" How long to hold onto the target.
Causes the activators first-person camera to switch to the view of this entity.
Trivia:
This entity was introduced in Half-Life (1998).
*/
class trigger_camera:CBaseTrigger
{
string m_strMoveTo;
float m_flDelay;
float m_flWait;
void(void) trigger_camera;
virtual void(entity, int) Trigger;
virtual void(string, string) SpawnKey;
};
void
trigger_camera::Trigger(entity act, int state)
{
UseTargets(act, TRIG_TOGGLE, m_flDelay);
if (m_strMoveTo) {
entity e = find(world, ::targetname, m_strMoveTo);
if (e) {
angles = vectoangles(e.origin - origin);
}
}
Client_TriggerCamera(act, origin, angles, m_flWait);
//eActivator.view2 = this;
dprint(sprintf("^2trigger_camera::^3Trigger^7: Camera at %v, %v, for %f sec/s requested\n",
origin, angles, m_flWait));
}
void
trigger_camera::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "wait":
m_flWait = stof(strValue);
break;
case "moveto":
m_strMoveTo = strValue;
break;
default:
CBaseTrigger::SpawnKey(strKey, strValue);
}
}
void
trigger_camera::trigger_camera(void)
{
CBaseTrigger::CBaseTrigger();
}

View File

@ -8,6 +8,7 @@ shared/spraylogo.cpp
shared/func_friction.cpp
shared/env_projectedtexture.cpp
shared/light_dynamic.cpp
shared/trigger_camera.cpp
shared/trigger_gravity.cpp
shared/info_particle_system.cpp
#endlist

View File

@ -0,0 +1,273 @@
/*
* Copyright (c) 2016-2020 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
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED trigger_camera (1 0 0) (-8 -8 -8) (8 8 8)
"targetname" Name
"target" Camera aims at this target.
"moveto" First path_corner entity, if present.
Trivia:
This entity was introduced in Half-Life (1998).
*/
enumflags
{
OCAMFL_CHANGED_ORIGIN,
OCAMFL_CHANGED_ANGLES,
OCAMFL_CHANGED_WAIT
};
#ifdef CLIENT
class trigger_camera
#else
class trigger_camera:CBaseTrigger
#endif
{
#ifdef CLIENT
#else
float m_flWait;
string m_strAimAt;
string m_strMoveTo;
entity m_eLooker;
#endif
void(void) trigger_camera;
#ifdef CLIENT
virtual void(float) ReceiveEntity;
#else
virtual void(void) NextPath;
virtual void(void) GoToTarget;
virtual void(entity, int) Trigger;
virtual void(void) Respawn;
virtual void(string, string) SpawnKey;
virtual float(entity, float) SendEntity;
virtual void(void) ParentUpdate;
#endif
};
#ifdef CLIENT
void
trigger_camera::ReceiveEntity(float flFlags)
{
if (flFlags & OCAMFL_CHANGED_ORIGIN) {
origin[0] = readcoord();
origin[1] = readcoord();
origin[2] = readcoord();
setorigin(this, origin);
}
if (flFlags & OCAMFL_CHANGED_ANGLES) {
angles[0] = readfloat();
angles[1] = readfloat();
angles[2] = readfloat();
}
int s = (float)getproperty(VF_ACTIVESEAT);
pSeat = &g_seats[s];
pSeat->m_vecCameraOrigin = origin;
pSeat->m_vecCameraAngle = angles;
if (flFlags & OCAMFL_CHANGED_WAIT) {
pSeat->m_flCameraTime = time + readfloat();
setproperty(VF_CL_VIEWANGLES, angles);
setproperty(VF_ANGLES, angles);
}
classname = "trigger_camera";
}
#else
float
trigger_camera::SendEntity(entity ePVSEnt, float flFlags)
{
if (ePVSEnt != m_eLooker)
return FALSE;
WriteByte(MSG_ENTITY, ENT_OLDCAMERA);
WriteFloat(MSG_ENTITY, flFlags);
if (flFlags & OCAMFL_CHANGED_ORIGIN) {
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
WriteCoord(MSG_ENTITY, origin[2]);
}
if (flFlags & OCAMFL_CHANGED_ANGLES) {
WriteFloat(MSG_ENTITY, angles[0]);
WriteFloat(MSG_ENTITY, angles[1]);
WriteFloat(MSG_ENTITY, angles[2]);
}
if (flFlags & OCAMFL_CHANGED_WAIT) {
WriteFloat(MSG_ENTITY, m_flWait);
}
return TRUE;
}
void
trigger_camera::ParentUpdate(void)
{
entity t = find(world, ::targetname, m_strAimAt);
if (t) {
angles = vectoangles(t.origin - origin);
}
if (net_origin != origin) {
net_origin = origin;
SendFlags |= OCAMFL_CHANGED_ORIGIN;
}
if (net_angles != angles) {
net_angles = angles;
SendFlags |= OCAMFL_CHANGED_ANGLES;
}
/* camera don't support parenting when we're following paths! */
if (m_parent && !m_strMoveTo) {
entity p = find(world, ::targetname, m_parent);
if (p)
SetOrigin(p.origin);
}
}
void
trigger_camera::GoToTarget(void)
{
float flTravelTime;
vector vecVelocity;
path_corner eNode;
eNode = (path_corner)find(world, ::targetname, target);
if (!eNode) {
return;
}
vecVelocity = (eNode.origin - origin);
flTravelTime = (vlen(vecVelocity) / eNode.m_flSpeed);
if (!flTravelTime) {
print("^1trigger_camera::^3GoToTarget^7: Distance short, going next\n");
think = NextPath;
/* because ltime may be 0 */
if (!ltime)
nextthink = ltime + 0.001f;
else
nextthink = ltime;
return;
}
velocity = (vecVelocity * (1 / flTravelTime));
think = NextPath;
nextthink = (ltime + flTravelTime);
}
void
trigger_camera::NextPath(void)
{
path_corner eNode;
eNode = (path_corner)find(world, ::targetname, target);
if (!eNode) {
return;
}
/* fire the path_corners' target */
eNode.Trigger(this, TRIG_TOGGLE);
SetOrigin(eNode.origin - (mins + maxs) * 0.5);
target = eNode.target;
velocity = [0,0,0];
/* warp next frame */
if (eNode.spawnflags & PC_TELEPORT) {
print(sprintf("^1trigger_camera::^3NextPath^7: Node %s wants %s to teleport\n", eNode.targetname, targetname));
think = NextPath;
nextthink = ltime;
return;
}
/* stop until triggered again */
if (eNode.spawnflags & PC_WAIT) {
return;
}
if (eNode.m_flWait > 0) {
think = GoToTarget;
nextthink = ltime + eNode.m_flWait;
} else {
GoToTarget();
}
}
/* TODO: Handle state? */
void
trigger_camera::Trigger(entity act, int state)
{
m_eLooker = act;
SetOrigin(m_oldOrigin);
velocity = [0,0,0];
think = __NULL__;
nextthink = 0.0f;
target = m_strMoveTo;
NextPath();
GoToTarget();
SendFlags |= OCAMFL_CHANGED_ORIGIN | OCAMFL_CHANGED_ANGLES | OCAMFL_CHANGED_WAIT;
}
void
trigger_camera::Respawn(void)
{
SetSolid(SOLID_NOT);
SetMovetype(MOVETYPE_PUSH);
SetModel(m_oldModel);
SetOrigin(m_oldOrigin);
}
void
trigger_camera::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "target":
m_strAimAt = strValue;
break;
case "moveto":
m_strMoveTo = strValue;
break;
case "wait":
m_flWait = stof(strValue);
break;
default:
CBaseTrigger::SpawnKey(strKey, strValue);
}
}
#endif
void
trigger_camera::trigger_camera(void)
{
#ifdef CLIENT
drawmask = MASK_ENGINE;
#else
m_flWait = 4.0f;
CBaseTrigger::CBaseTrigger();
#endif
}

View File

@ -27,6 +27,7 @@ enum
ENT_SPRITE,
ENT_SPRAY,
ENT_DECAL,
ENT_OLDCAMERA,
ENT_SEPARATOR
};