mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-18 13:00:21 +02:00
278 lines
6.2 KiB
C++
278 lines
6.2 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
|
|
===========================================================================
|
|
*/
|
|
|
|
// gibs.cpp: Gibs - nuff said
|
|
|
|
#include "gibs.h"
|
|
#include "decals.h"
|
|
#include "level.h"
|
|
#include "g_phys.h"
|
|
|
|
Event EV_ThrowGib
|
|
(
|
|
"throwgib",
|
|
EV_DEFAULT,
|
|
"eif",
|
|
"ent velocity scale",
|
|
"Throw a gib.",
|
|
EV_NORMAL
|
|
);
|
|
|
|
CLASS_DECLARATION(Mover, Gib, "gib") {
|
|
{&EV_ThrowGib, &Gib::Throw },
|
|
{&EV_Touch, &Gib::Splat },
|
|
{&EV_Stop, &Gib::Stop },
|
|
{&EV_Damage, &Gib::Damage},
|
|
{NULL, NULL }
|
|
};
|
|
|
|
Gib::Gib(
|
|
str name,
|
|
qboolean blood_trail,
|
|
str bloodtrailname,
|
|
str bloodspurtname,
|
|
str bloodsplatname,
|
|
float bloodsplatsize,
|
|
float pitch
|
|
)
|
|
{
|
|
setSize(Vector("0 0 0"), Vector("0 0 0"));
|
|
|
|
if (name.length()) {
|
|
setModel(name.c_str());
|
|
}
|
|
|
|
setMoveType(MOVETYPE_GIB);
|
|
setSolidType(SOLID_BBOX);
|
|
takedamage = DAMAGE_YES;
|
|
sprayed = false;
|
|
fadesplat = true;
|
|
scale = 2.0f;
|
|
|
|
next_bleed_time = 0;
|
|
|
|
final_pitch = pitch;
|
|
|
|
if (blood_trail) {
|
|
// Make a blood emitter and bind it to the head
|
|
blood = new Mover;
|
|
|
|
if (bloodtrailname.length()) {
|
|
blood->setModel(bloodtrailname.c_str());
|
|
}
|
|
|
|
blood->setMoveType(MOVETYPE_BOUNCE);
|
|
blood->setSolidType(SOLID_NOT);
|
|
blood->bind(this);
|
|
|
|
// Save the blood spurt name
|
|
|
|
if (bloodspurtname.length()) {
|
|
blood_spurt_name = bloodspurtname;
|
|
}
|
|
|
|
// Save the blood splat name
|
|
|
|
if (bloodsplatname.length()) {
|
|
blood_splat_name = bloodsplatname;
|
|
}
|
|
|
|
blood_splat_size = bloodsplatsize;
|
|
} else {
|
|
blood = NULL;
|
|
}
|
|
|
|
Sound("snd_decap", CHAN_BODY, 1, 300);
|
|
}
|
|
|
|
Gib::~Gib()
|
|
{
|
|
if (blood) {
|
|
blood->PostEvent(EV_Remove, 0);
|
|
}
|
|
blood = NULL;
|
|
}
|
|
|
|
Gib::Gib()
|
|
{
|
|
if (LoadingSavegame) {
|
|
return;
|
|
}
|
|
|
|
setSize(Vector("0 0 0"), Vector("0 0 0"));
|
|
setModel("gib1.def");
|
|
setMoveType(MOVETYPE_GIB);
|
|
setSolidType(SOLID_BBOX);
|
|
sprayed = 0;
|
|
fadesplat = true;
|
|
scale = 2.0f;
|
|
}
|
|
|
|
void Gib::Stop(Event *ev)
|
|
{
|
|
//setSolidType( SOLID_NOT );
|
|
if (blood) {
|
|
blood->PostEvent(EV_Remove, 0);
|
|
}
|
|
blood = NULL;
|
|
}
|
|
|
|
void Gib::Splat(Event *ev)
|
|
{
|
|
if (g_gametype->integer != GT_SINGLE_PLAYER) {
|
|
return;
|
|
}
|
|
|
|
if (sprayed > 3) {
|
|
//setSolidType(SOLID_NOT);
|
|
return;
|
|
}
|
|
|
|
sprayed++;
|
|
scale -= 0.2f;
|
|
|
|
// Stop spinning / force to final pitch
|
|
|
|
avelocity = vec_zero;
|
|
|
|
if (final_pitch != NO_FINAL_PITCH) {
|
|
angles[PITCH] = final_pitch;
|
|
setAngles(angles);
|
|
}
|
|
|
|
SprayBlood(origin);
|
|
Sound("snd_gibhit");
|
|
}
|
|
|
|
void Gib::Damage(Event *ev)
|
|
{
|
|
Vector direction;
|
|
Entity *blood;
|
|
Vector dir;
|
|
|
|
if (next_bleed_time > level.time) {
|
|
return;
|
|
}
|
|
|
|
direction = ev->GetVector(5);
|
|
|
|
// Spawn a blood spurt
|
|
|
|
if (blood_spurt_name.length() > 0) {
|
|
blood = new Animate;
|
|
blood->setModel(blood_spurt_name.c_str());
|
|
|
|
dir[0] = -direction[0];
|
|
dir[1] = -direction[1];
|
|
dir[2] = -direction[2];
|
|
|
|
blood->angles = dir.toAngles();
|
|
blood->setAngles(blood->angles);
|
|
|
|
blood->setOrigin(centroid);
|
|
blood->origin.copyTo(blood->edict->s.origin2);
|
|
blood->setSolidType(SOLID_NOT);
|
|
|
|
blood->PostEvent(EV_Remove, 1);
|
|
|
|
next_bleed_time = level.time + 0.5;
|
|
}
|
|
}
|
|
|
|
void Gib::SprayBlood(Vector start)
|
|
{
|
|
Vector norm;
|
|
trace_t trace;
|
|
Vector trace_end;
|
|
|
|
trace_end = velocity;
|
|
trace_end.normalize();
|
|
trace_end *= 1000;
|
|
trace_end += start;
|
|
|
|
trace = G_Trace(start, vec_zero, vec_zero, trace_end, this, MASK_SOLID, false, "Gib::SprayBlood");
|
|
|
|
if (HitSky(&level.impact_trace) || (!level.impact_trace.ent) || (level.impact_trace.ent->solid != SOLID_BSP)) {
|
|
return;
|
|
}
|
|
|
|
// Do a bloodsplat
|
|
if (blood_splat_name.length()) {
|
|
Decal *decal = new Decal;
|
|
decal->setShader(blood_splat_name);
|
|
decal->setOrigin(Vector(trace.endpos) + (Vector(level.impact_trace.plane.normal) * 0.2f));
|
|
decal->setDirection(level.impact_trace.plane.normal);
|
|
decal->setOrientation("random");
|
|
decal->setRadius(blood_splat_size + G_Random(blood_splat_size));
|
|
}
|
|
}
|
|
|
|
void Gib::ClipGibVelocity(void)
|
|
{
|
|
if (velocity[0] < -400) {
|
|
velocity[0] = -400;
|
|
} else if (velocity[0] > 400) {
|
|
velocity[0] = 400;
|
|
}
|
|
if (velocity[1] < -400) {
|
|
velocity[1] = -400;
|
|
} else if (velocity[1] > 400) {
|
|
velocity[1] = 400;
|
|
}
|
|
if (velocity[2] < 200) {
|
|
velocity[2] = 200; // always some upwards
|
|
} else if (velocity[2] > 600) {
|
|
velocity[2] = 600;
|
|
}
|
|
}
|
|
|
|
void Gib::SetVelocity(float damage)
|
|
{
|
|
velocity[0] = 100.0 * crandom();
|
|
velocity[1] = 100.0 * crandom();
|
|
velocity[2] = 200.0 + 100.0 * random();
|
|
|
|
avelocity = Vector(G_Random(600), G_Random(600), G_Random(600));
|
|
|
|
if ((damage < -150) && (G_Random() > 0.95f)) {
|
|
velocity *= 2.0f;
|
|
} else if (damage < -100) {
|
|
velocity *= 1.5f;
|
|
}
|
|
|
|
ClipGibVelocity();
|
|
}
|
|
|
|
void Gib::Throw(Event *ev)
|
|
{
|
|
Entity *ent;
|
|
|
|
ent = ev->GetEntity(1);
|
|
setOrigin(ent->centroid);
|
|
origin.copyTo(edict->s.origin2);
|
|
SetVelocity(ev->GetInteger(2));
|
|
edict->s.scale = ev->GetFloat(3);
|
|
PostEvent(EV_FadeOut, 10 + G_Random(5));
|
|
}
|
|
|
|
void CreateGibs(Entity *ent, float damage, float scale, int num, const char *modelname) {}
|