openmohaa/code/game/windows.cpp

189 lines
3.8 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
===========================================================================
*/
// windows.cpp: Window class
//
#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 );
}