/* =========================================================================== 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 ); }