mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
190 lines
4.5 KiB
C++
190 lines
4.5 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 "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()
|
|
{
|
|
if (LoadingSavegame) {
|
|
return;
|
|
}
|
|
|
|
edict->s.eType = ET_GENERAL;
|
|
health = 250;
|
|
max_health = health;
|
|
deadflag = 0;
|
|
takedamage = DAMAGE_YES;
|
|
|
|
m_iDebrisType = WINDOW_GLASS;
|
|
|
|
PostEvent(EV_Window_Setup, EV_POSTSPAWN);
|
|
}
|
|
|
|
void WindowObject::Archive(Archiver& arc)
|
|
{
|
|
Entity::Archive(arc);
|
|
|
|
arc.ArchiveInteger(&m_iDebrisType);
|
|
arc.ArchiveString(&m_sBrokenModel);
|
|
}
|
|
|
|
void WindowObject::WindowSetup(Event *ev)
|
|
{
|
|
Entity *pEnt;
|
|
|
|
setMoveType(MOVETYPE_NONE);
|
|
setSolidType(SOLID_BSP);
|
|
setContents(CONTENTS_TRIGGER);
|
|
|
|
if (Target().length()) {
|
|
// If a target is defined,
|
|
// find it and set the model from it
|
|
pEnt = (Entity *)G_FindTarget(NULL, Target());
|
|
|
|
if (pEnt) {
|
|
m_sBrokenModel = pEnt->model;
|
|
|
|
// Don't keep the original entity
|
|
pEnt->PostEvent(EV_Remove, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
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 *= 10;
|
|
}
|
|
|
|
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 = (mins + maxs) * 0.5;
|
|
vCenter += origin;
|
|
|
|
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();
|
|
|
|
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);
|
|
}
|