openmohaa/code/fgame/portal.cpp
2023-08-15 01:27:35 +02:00

162 lines
3.6 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// portal.cpp: Portals - surfaces that are mirrors or cameras
#include "portal.h"
#include "game.h"
/*QUAKED portal_surface (1 0 1) (-8 -8 -8) (8 8 8)
The portal surface nearest this entity will show a view from the targeted portal_camera, or a mirror view if untargeted.
*/
Event EV_Portal_LocateCamera
(
"locatecamera",
EV_DEFAULT,
NULL,
NULL,
"Locates the camera position.",
EV_NORMAL
);
CLASS_DECLARATION( Entity, PortalSurface, "portal_surface" )
{
{ &EV_Portal_LocateCamera, &PortalSurface::LocateCamera },
{ NULL, NULL }
};
void PortalSurface::LocateCamera
(
Event *ev
)
{
Entity *owner;
Entity *target;
Vector dir;
owner = ( Entity * )G_FindTarget( NULL, Target() );
if ( !owner )
{
// No target, just a mirror
VectorCopy( edict->s.origin, edict->s.origin2 );
return;
}
// skinNum holds the rotate offset
edict->s.skinNum = owner->edict->s.skinNum;
VectorCopy( owner->origin, edict->s.origin2 );
// see if the portal_camera has a target
target = ( Entity * )G_FindTarget( NULL, owner->Target() );
if ( target )
{
dir = target->origin - owner->origin;
dir.normalize();
setAngles( dir.toAngles() );
}
else
{
setAngles( owner->angles );
dir = owner->orientation[ 0 ];
}
}
PortalSurface::PortalSurface
(
)
{
if ( LoadingSavegame )
{
// Archive function will setup all necessary data
return;
}
VectorClear( edict->r.mins );
VectorClear( edict->r.maxs );
gi.linkentity( edict );
edict->r.svFlags = SVF_PORTAL | SVF_SENDPVS;
edict->s.eType = ET_PORTAL;
PostEvent( EV_Portal_LocateCamera, EV_POSTSPAWN );
}
/*QUAKED portal_camera (1 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate
The target for a portal_surface. You can set either angles or target another entity to determine the direction of view.
"roll" an angle modifier to orient the camera around the target vector;
*/
Event EV_Portal_Roll
(
"roll",
EV_DEFAULT,
"f",
"roll",
"Sets the portal camera's roll.",
EV_NORMAL
);
CLASS_DECLARATION( Entity, PortalCamera, "portal_camera" )
{
{ &EV_Portal_Roll, &PortalCamera::Roll },
{ NULL, NULL }
};
void PortalCamera::Roll
(
Event *ev
)
{
float roll = ev->GetFloat( 1 );
// skinNum holds the roll
edict->s.skinNum = roll/360.0f * 256;
}
PortalCamera::PortalCamera
(
)
{
if ( LoadingSavegame )
{
// Archive function will setup all necessary data
return;
}
VectorClear( edict->r.mins );
VectorClear( edict->r.maxs );
// No roll on the camera by default
edict->s.skinNum = 0;
gi.linkentity( edict );
}