nuclide/src/gs-entbase/shared/func_monitor.qc

338 lines
7.6 KiB
Plaintext

/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* 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 func_monitor (0 .5 .8) ?
A monitor that renders the view of a linked point_camera entity.
-------- KEYS --------
"targetname" : Name
"target" : Camera it's linked to.
-------- INPUTS --------
"Enable" : Turns the monitor on
"Disable" : Turns the monitor on.
"Toggle" : Toggles the state of the monitor between on and off.
-------- TRIVIA --------
This entity was introduced in Half-Life 2 (2004).
*/
#ifdef CLIENT
int g_iRenderTargetActive;
float g_flRenderTargetFOV;
vector g_iRenderTargetSize;
vector g_vecRenderTargetPos;
vector g_vecRenderTargetAngles;
void
RenderTarget_Monitor_Update(void)
{
if (!g_iRenderTargetActive) {
return;
}
clearscene();
setviewprop(VF_RT_DESTCOLOUR, "base", (float)1, g_iRenderTargetSize);
setviewprop(VF_SIZE, g_iRenderTargetSize);
setviewprop(VF_DRAWENGINESBAR, (float)0);
setviewprop(VF_ORIGIN, g_vecRenderTargetPos);
setviewprop(VF_ANGLES, g_vecRenderTargetAngles);
setviewprop(VF_AFOV, g_flRenderTargetFOV);
/* TODO: This is ideally where fog parms should be set... :/ */
addentities(MASK_ENGINE);
renderscene();
setviewprop(VF_RT_DESTCOLOUR, "");
}
#endif
enumflags
{
MONITORFL_CHANGED_BASE,
MONITORFL_CHANGED_ORIGIN,
MONITORFL_CHANGED_ANGLES,
MONITORFL_CHANGED_FOV,
MONITORFL_CHANGED_ASPECT,
MONITORFL_CHANGED_FOGCOLOR,
MONITORFL_CHANGED_FOGSTART,
MONITORFL_CHANGED_FOGEND,
MONITORFL_CHANGED_STATUS
};
class func_monitor:NSRenderableEntity
{
/* these mirror the fields of a point_camera */
vector m_vecCamOrigin;
vector m_vecCamAngles;
int m_iCamValue;
float m_flFOV;
int m_iUseSAR;
int m_iUseFog;
vector m_vecFogColor;
float m_flFogStart;
float m_flFogEnd;
void(void) func_monitor;
#ifdef CLIENT
int m_iValue;
virtual void(float,float) ReceiveEntity;
#else
virtual void(void) Respawn;
virtual void(void) EvaluateEntity;
virtual float(entity, float) SendEntity;
virtual void(string, string) SpawnKey;
virtual void(entity, int) Trigger;
virtual void(entity, string, string) Input;
#endif
};
#ifdef CLIENT
void
func_monitor::ReceiveEntity(float flNew, float flFlags)
{
if (flFlags & MONITORFL_CHANGED_ORIGIN) {
modelindex = readfloat();
origin[0] = readcoord();
origin[1] = readcoord();
origin[2] = readcoord();
}
if (flFlags & MONITORFL_CHANGED_ORIGIN) {
m_vecCamOrigin[0] = readcoord();
m_vecCamOrigin[1] = readcoord();
m_vecCamOrigin[2] = readcoord();
}
if (flFlags & MONITORFL_CHANGED_ANGLES) {
m_vecCamAngles[0] = readfloat();
m_vecCamAngles[1] = readfloat();
m_vecCamAngles[2] = readfloat();
}
if (flFlags & MONITORFL_CHANGED_FOV)
m_flFOV = readbyte();
if (flFlags & MONITORFL_CHANGED_ASPECT)
m_iUseSAR = readbyte();
if (flFlags & MONITORFL_CHANGED_FOGCOLOR) {
m_vecFogColor[0] = readbyte();
m_vecFogColor[1] = readbyte();
m_vecFogColor[2] = readbyte();
}
if (flFlags & MONITORFL_CHANGED_FOGSTART)
m_flFogStart = readshort();
if (flFlags & MONITORFL_CHANGED_FOGEND)
m_flFogEnd = readshort();
if (flFlags & MONITORFL_CHANGED_STATUS)
m_iValue = readbyte();
classname = "func_monitor";
solid = SOLID_BSP;
movetype = MOVETYPE_NONE;
setorigin(this, origin);
setsize(this, mins, maxs);
g_iRenderTargetActive = m_iValue;
if (!m_iValue) {
return;
}
g_flRenderTargetFOV = m_flFOV;
g_iRenderTargetSize = [320, 240];
g_vecRenderTargetPos = m_vecCamOrigin;
g_vecRenderTargetAngles = m_vecCamAngles;
}
#else
float
func_monitor::SendEntity(entity ePEnt, float flFlags)
{
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
return (0);
WriteByte(MSG_ENTITY, ENT_MONITOR);
WriteFloat(MSG_ENTITY, flFlags);
if (flFlags & MONITORFL_CHANGED_BASE) {
WriteFloat(MSG_ENTITY, modelindex);
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[0]);
}
if (flFlags & MONITORFL_CHANGED_ORIGIN) {
WriteCoord(MSG_ENTITY, m_vecCamOrigin[0]);
WriteCoord(MSG_ENTITY, m_vecCamOrigin[1]);
WriteCoord(MSG_ENTITY, m_vecCamOrigin[2]);
}
if (flFlags & MONITORFL_CHANGED_ANGLES) {
WriteFloat(MSG_ENTITY, m_vecCamAngles[0]);
WriteFloat(MSG_ENTITY, m_vecCamAngles[1]);
WriteFloat(MSG_ENTITY, m_vecCamAngles[2]);
}
if (flFlags & MONITORFL_CHANGED_FOV)
WriteByte(MSG_ENTITY, m_flFOV);
if (flFlags & MONITORFL_CHANGED_ASPECT)
WriteByte(MSG_ENTITY, m_iUseSAR);
if (flFlags & MONITORFL_CHANGED_FOGCOLOR) {
WriteByte(MSG_ENTITY, m_vecFogColor[0]);
WriteByte(MSG_ENTITY, m_vecFogColor[1]);
WriteByte(MSG_ENTITY, m_vecFogColor[2]);
}
if (flFlags & MONITORFL_CHANGED_FOGSTART)
WriteShort(MSG_ENTITY, m_flFogStart);
if (flFlags & MONITORFL_CHANGED_FOGEND)
WriteShort(MSG_ENTITY, m_flFogEnd);
if (flFlags & MONITORFL_CHANGED_STATUS)
WriteByte(MSG_ENTITY, m_iValue);
return (1);
}
void
func_monitor::EvaluateEntity(void)
{
if (ATTR_CHANGED(origin)) {
SetSendFlags(MONITORFL_CHANGED_BASE);
}
SAVE_STATE(origin);
/* this monitor is disabled */
if (!m_iValue)
return;
point_camera viewer;
viewer = (point_camera)find(world, ::targetname, target);
if (!viewer)
return;
/* camera is disabled */
if (!viewer.m_iValue)
return;
if (m_vecCamOrigin != viewer.origin) {
m_vecCamOrigin = viewer.origin;
SetSendFlags(MONITORFL_CHANGED_ORIGIN);
}
if (m_vecCamAngles != viewer.angles) {
m_vecCamAngles = viewer.angles;
SetSendFlags(MONITORFL_CHANGED_ANGLES);
}
if (m_flFOV != viewer.m_flFOV) {
m_flFOV = viewer.m_flFOV;
SetSendFlags(MONITORFL_CHANGED_FOV);
}
if (m_iUseSAR != viewer.m_iUseSAR) {
m_iUseSAR = viewer.m_iUseSAR;
SetSendFlags(MONITORFL_CHANGED_ASPECT);
}
if (m_vecFogColor != viewer.m_vecFogColor) {
m_vecFogColor = viewer.m_vecFogColor;
SetSendFlags(MONITORFL_CHANGED_FOGCOLOR);
}
if (m_flFogStart != viewer.m_flFogStart) {
m_flFogStart = viewer.m_flFogStart;
SetSendFlags(MONITORFL_CHANGED_FOGSTART);
}
if (m_flFogEnd != viewer.m_flFogEnd) {
m_flFogEnd = viewer.m_flFogEnd;
SetSendFlags(MONITORFL_CHANGED_FOGEND);
}
if (m_flFogEnd != viewer.m_flFogEnd) {
m_flFogEnd = viewer.m_flFogEnd;
SetSendFlags(MONITORFL_CHANGED_STATUS);
}
}
void
func_monitor::Trigger(entity act, int state)
{
switch (state) {
case TRIG_OFF:
m_iValue = 0;
break;
case TRIG_ON:
m_iValue = 1;
break;
default:
m_iValue = 1 - m_iValue;
}
SetSendFlags(MONITORFL_CHANGED_STATUS);
}
void
func_monitor::Input(entity eAct, string strInput, string strData)
{
switch (strInput) {
case "Enable":
Trigger(eAct, TRIG_ON);
break;
case "Disable":
Trigger(eAct, TRIG_OFF);
break;
case "Toggle":
Trigger(eAct, TRIG_TOGGLE);
break;
default:
super::Input(eAct, strInput, strData);
}
}
void
func_monitor::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
default:
super::SpawnKey(strKey, strValue);
}
}
void
func_monitor::Respawn(void)
{
SetSolid(SOLID_BSP);
SetMovetype(MOVETYPE_NONE);
SetOrigin(GetSpawnOrigin());
SetAngles(GetSpawnAngles());
SetModel(GetSpawnModel());
m_iValue = TRUE;
}
#endif
void
func_monitor::func_monitor(void)
{
#ifdef CLIENT
drawmask = MASK_ENGINE;
#endif
}