openmohaa/code/fgame/windows.cpp

191 lines
4.5 KiB
C++
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
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
//
2023-04-29 21:56:38 +02:00
#include "g_phys.h"
2016-03-27 11:49:47 +02:00
#include "windows.h"
2023-01-29 20:59:31 +01:00
#include "game.h"
2016-03-27 11:49:47 +02:00
Event EV_Window_Setup
(
2023-11-26 19:54:07 +01:00
"_Windowsetup",
EV_CODEONLY,
NULL,
NULL,
"Does the post spawn setup of the Window"
2016-03-27 11:49:47 +02:00
);
Event EV_Window_SetDebris
(
2023-11-26 19:54:07 +01:00
"debristype",
EV_DEFAULT,
"i",
"type",
"Sets the debris type of the Window"
2016-03-27 11:49:47 +02:00
);
2023-11-26 19:54:07 +01:00
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 }
2016-03-27 11:49:47 +02:00
};
WindowObject::WindowObject()
{
2024-11-05 22:02:08 +01:00
if (LoadingSavegame) {
return;
}
edict->s.eType = ET_GENERAL;
health = 250;
max_health = health;
deadflag = 0;
takedamage = DAMAGE_YES;
2023-11-26 19:54:07 +01:00
m_iDebrisType = WINDOW_GLASS;
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
PostEvent(EV_Window_Setup, EV_POSTSPAWN);
2016-03-27 11:49:47 +02:00
}
2023-11-26 19:54:07 +01:00
void WindowObject::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
Entity::Archive(arc);
2023-11-26 19:54:07 +01:00
arc.ArchiveInteger(&m_iDebrisType);
arc.ArchiveString(&m_sBrokenModel);
2016-03-27 11:49:47 +02:00
}
2023-11-26 19:54:07 +01:00
void WindowObject::WindowSetup(Event *ev)
2016-03-27 11:49:47 +02:00
{
2023-11-26 19:54:07 +01:00
Entity *pEnt;
2016-03-27 11:49:47 +02:00
2024-11-05 22:02:08 +01:00
setMoveType(MOVETYPE_NONE);
2023-11-26 19:54:07 +01:00
setSolidType(SOLID_BSP);
2024-11-05 22:02:08 +01:00
setContents(CONTENTS_TRIGGER);
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
if (Target().length()) {
2024-11-05 22:02:08 +01:00
// If a target is defined,
// find it and set the model from it
2023-11-26 19:54:07 +01:00
pEnt = (Entity *)G_FindTarget(NULL, Target());
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
if (pEnt) {
m_sBrokenModel = pEnt->model;
2016-03-27 11:49:47 +02:00
2024-11-05 22:02:08 +01:00
// Don't keep the original entity
2023-11-26 19:54:07 +01:00
pEnt->PostEvent(EV_Remove, 0);
}
}
2016-03-27 11:49:47 +02:00
}
2023-11-26 19:54:07 +01:00
void WindowObject::WindowDebrisType(Event *ev)
2016-03-27 11:49:47 +02:00
{
2023-11-26 19:54:07 +01:00
m_iDebrisType = ev->GetInteger(1);
2016-03-27 11:49:47 +02:00
}
2023-11-26 19:54:07 +01:00
void WindowObject::WindowDamaged(Event *ev)
2016-03-27 11:49:47 +02:00
{
2023-11-26 19:54:07 +01:00
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 *= 10;
2023-11-26 19:54:07 +01:00
}
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);
}
2016-03-27 11:49:47 +02:00
}
2023-11-26 19:54:07 +01:00
void WindowObject::WindowKilled(Event *ev)
2016-03-27 11:49:47 +02:00
{
2023-11-26 19:54:07 +01:00
Vector vCenter;
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
setSolidType(SOLID_NOT);
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
hideModel();
takedamage = DAMAGE_NO;
2016-03-27 11:49:47 +02:00
2024-11-05 22:03:43 +01:00
vCenter = (mins + maxs) * 0.5;
vCenter += origin;
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
gi.SetBroadcastVisible(vCenter, vCenter);
gi.MSG_StartCGM(BG_MapCGMToProtocol(g_protocol, CGM_MAKE_WINDOW_DEBRIS));
gi.MSG_WriteCoord(vCenter[0]);
gi.MSG_WriteCoord(vCenter[1]);
gi.MSG_WriteCoord(vCenter[2]);
gi.MSG_WriteByte(m_iDebrisType);
gi.MSG_EndCGM();
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
if (m_sBrokenModel.length()) {
Entity *ent = new Entity;
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
ent->takedamage = DAMAGE_NO;
ent->setModel(m_sBrokenModel);
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
ent->setMoveType(MOVETYPE_NONE);
ent->setSolidType(SOLID_BSP);
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
setModel(m_sBrokenModel);
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
if (spawnflags & WINDOW_BROKEN_BLOCK) {
ent->setContents(CONTENTS_MONSTERCLIP | CONTENTS_PLAYERCLIP);
} else {
ent->setContents(CONTENTS_SHOOTONLY);
}
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
ent->setOrigin(origin);
ent->showModel();
}
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
deadflag = DEAD_DEAD;
2016-03-27 11:49:47 +02:00
2023-11-26 19:54:07 +01:00
// remove the window
PostEvent(EV_Remove, 0);
2016-03-27 11:49:47 +02:00
}