Files
2025-07-19 23:30:20 +02:00

140 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);
}