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