/* =========================================================================== 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 =========================================================================== */ // windows.cpp: Window class // #include "g_phys.h" #include "windows.h" #include "game.h" Event EV_Window_Setup ( "_Windowsetup", EV_CODEONLY, NULL, NULL, "Does the post spawn setup of the Window" ); Event EV_Window_SetDebris ( "debristype", EV_DEFAULT, "i", "type", "Sets the debris type of the Window" ); CLASS_DECLARATION( Entity, WindowObject, "func_window" ) { { &EV_Window_Setup, &WindowObject::WindowSetup }, { &EV_Damage, &WindowObject::WindowDamaged }, { &EV_Killed, &WindowObject::WindowKilled }, { &EV_Window_SetDebris, &WindowObject::WindowDebrisType }, { NULL, NULL } }; WindowObject::WindowObject() { m_iDebrisType = WINDOW_GLASS; PostEvent( EV_Window_Setup, EV_POSTSPAWN ); } void WindowObject::Archive( Archiver& arc ) { arc.ArchiveInteger( &m_iDebrisType ); arc.ArchiveString( &m_sBrokenModel ); } void WindowObject::WindowSetup( Event *ev ) { Entity *pEnt; setSolidType( SOLID_BSP ); if( Target().length() ) { pEnt = ( Entity * )G_FindTarget( NULL, Target() ); if( pEnt ) { // set the broken model to the target model m_sBrokenModel = pEnt->model; pEnt->PostEvent( EV_Remove, 0 ); } } takedamage = DAMAGE_YES; if( health <= 0.1f ) { health = 100.0f; } } void WindowObject::WindowDebrisType( Event *ev ) { m_iDebrisType = ev->GetInteger( 1 ); } void WindowObject::WindowDamaged( Event *ev ) { int iMeansOfDeath; int iDamage; Vector vRight; Vector vForward; Vector vDir; Event *event; if( !takedamage ) { return; } iDamage = ev->GetInteger( 2 ); iMeansOfDeath = ev->GetInteger( 9 ); if( iMeansOfDeath == MOD_BASH ) { // double damage for bash iDamage *= 2; } else if( iMeansOfDeath == MOD_EXPLOSION ) { // instant break iDamage = health; } health -= iDamage; if( health <= 0.0f ) { event = new Event( EV_Killed ); event->AddEntity( ev->GetEntity( 1 ) ); event->AddInteger( ev->GetInteger( 2 ) ); event->AddEntity( ev->GetEntity( 3 ) ); ProcessEvent( event ); } } void WindowObject::WindowKilled( Event *ev ) { Vector vCenter; setSolidType( SOLID_NOT ); hideModel(); takedamage = DAMAGE_NO; vCenter = origin + mins + maxs; gi.SetBroadcastVisible( vCenter, vCenter ); gi.MSG_StartCGM( 24 ); gi.MSG_WriteCoord( vCenter[ 0 ] ); gi.MSG_WriteCoord( vCenter[ 1 ] ); gi.MSG_WriteCoord( vCenter[ 2 ] ); gi.MSG_WriteByte( m_iDebrisType ); gi.MSG_EndCGM(); if( m_sBrokenModel.length() ) { Entity *ent = new Entity; ent->takedamage = DAMAGE_NO; ent->setModel( m_sBrokenModel ); ent->setMoveType( MOVETYPE_NONE ); ent->setSolidType( SOLID_BSP ); setModel( m_sBrokenModel ); if( spawnflags & WINDOW_BROKEN_BLOCK ) { ent->setContents( CONTENTS_MONSTERCLIP | CONTENTS_PLAYERCLIP ); } else { ent->setContents( CONTENTS_SHOOTONLY ); } ent->setOrigin( origin ); ent->showModel(); } deadflag = DEAD_DEAD; // remove the window PostEvent( EV_Remove, 0 ); }