openmohaa/code/fgame/smokegrenade.cpp

291 lines
7 KiB
C++
Raw Normal View History

/*
===========================================================================
Copyright (C) 2024 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
===========================================================================
*/
#include "smokegrenade.h"
#include "smokesprite.h"
#include "level.h"
2023-10-03 18:30:19 +02:00
#include "sentient.h"
Event EV_SmokeGrenade_SetSpawnRate
(
"spawnrate",
EV_DEFAULT,
"f",
"rate",
"sets how many smoke volumes are spawned per second"
);
Event EV_SmokeGrenade_SetBouncefactor
(
"bouncefactor",
EV_DEFAULT,
"f",
"factor",
"sets how far smoke volumes bounce when they collide with something"
);
Event EV_SmokeGrenade_SetLife
(
"life",
EV_DEFAULT,
"f",
"life",
"sets how long the smoke emitter lives"
);
Event EV_SmokeGrenade_SetSpawnLife
(
"spawnlife",
EV_DEFAULT,
"f",
"life",
"sets how long each smoke volume lives"
);
Event EV_SmokeGrenade_SetScalerate
(
"scalerate",
EV_DEFAULT,
"f",
"rate",
"sets how fast the smoke volume grows"
);
Event EV_SmokeGrenade_SetVelocity
(
"velocity",
EV_DEFAULT,
"fff",
"vel_x vel_y vel_z",
"sets how fast the smoke volume moves away, with x forward and z up"
);
Event EV_SmokeGrenade_SetSpin
(
2023-11-14 14:09:52 +01:00
"spin",
EV_DEFAULT,
"f",
"avel",
"sets the number of rotations per second for this entity around its z axis"
);
Event EV_SmokeGrenade_SetOffset
(
"offset",
EV_DEFAULT,
"fff",
"offset_x offset_y offset_z",
"sets offset of the smoke volume from the entity"
);
Event EV_SmokeGrenade_SetScale
(
"scale",
EV_DEFAULT,
"f",
"scale",
"sets initial scale of each smoke volume"
);
Event EV_SmokeGrenade_SetFadein
(
"fadein",
EV_DEFAULT,
"f",
"time",
"sets fadein time from 0 alpha to 1 alpha, in seconds"
);
Event EV_SmokeGrenade_SetFadedelay
(
"fadedelay",
EV_DEFAULT,
"f",
"time",
"sets how long the entity waits until fading out from 1 alpha to 0 alpha, in seconds"
);
Event EV_SmokeGrenade_SetMaxAlpha
(
"maxalpha",
EV_DEFAULT,
"f",
"alpha",
"sets maximum opacity of an individual smoke particle, in 0-1 range"
);
CLASS_DECLARATION(EffectEntity, SmokeGrenade, "smokegrenade") {
{&EV_SmokeGrenade_SetSpawnRate, &SmokeGrenade::EventSetSpawnrate },
{&EV_SmokeGrenade_SetBouncefactor, &SmokeGrenade::EventSetBouncefactor},
{&EV_SmokeGrenade_SetLife, &SmokeGrenade::EventSetLife },
{&EV_SmokeGrenade_SetSpawnLife, &SmokeGrenade::EventSetSpawnLife },
{&EV_SmokeGrenade_SetScalerate, &SmokeGrenade::EventSetScalerate },
{&EV_SmokeGrenade_SetVelocity, &SmokeGrenade::EventSetVelocity },
{&EV_SmokeGrenade_SetSpin, &SmokeGrenade::EventSetSpin },
{&EV_SmokeGrenade_SetOffset, &SmokeGrenade::EventSetOffset },
{&EV_SmokeGrenade_SetScale, &SmokeGrenade::EventSetScale },
{&EV_SmokeGrenade_SetFadein, &SmokeGrenade::EventSetFadein },
{&EV_SmokeGrenade_SetFadedelay, &SmokeGrenade::EventSetFadedelay },
{&EV_SmokeGrenade_SetMaxAlpha, &SmokeGrenade::EventSetMaxAlpha },
{NULL, NULL }
};
void SmokeGrenade::EventSetSpawnrate(Event *ev)
{
float rate = ev->GetFloat(1);
if (rate < 0.001f) {
rate = 0.001f;
}
spawnRate = 1000.0f / rate;
}
void SmokeGrenade::EventSetBouncefactor(Event *ev)
{
bounceFactor = ev->GetFloat(1);
}
void SmokeGrenade::EventSetLife(Event *ev)
{
nextRemoveTime = level.time + ev->GetFloat(1);
}
void SmokeGrenade::EventSetSpawnLife(Event *ev)
{
spawnLife = ev->GetFloat(1);
}
void SmokeGrenade::EventSetScalerate(Event *ev)
{
scaleRate = ev->GetFloat(1);
}
void SmokeGrenade::EventSetVelocity(Event *ev)
{
velocity[0] = ev->GetFloat(1);
velocity[1] = ev->GetFloat(2);
velocity[2] = ev->GetFloat(3);
}
void SmokeGrenade::EventSetSpin(Event *ev)
{
spinRate = ev->GetFloat(1);
}
void SmokeGrenade::EventSetOffset(Event *ev)
{
offset[0] = ev->GetFloat(1);
offset[1] = ev->GetFloat(2);
offset[2] = ev->GetFloat(3);
}
void SmokeGrenade::EventSetScale(Event *ev)
{
scale = ev->GetFloat(1) * 0.5;
}
void SmokeGrenade::EventSetFadein(Event *ev)
{
fadeIn = ev->GetFloat(1);
}
void SmokeGrenade::EventSetFadedelay(Event *ev)
{
fadeDelay = ev->GetFloat(1);
}
void SmokeGrenade::EventSetMaxAlpha(Event *ev)
{
maxAlpha = ev->GetFloat(1);
}
SmokeGrenade::SmokeGrenade()
{
flags |= FL_THINK;
nextRemoveTime = level.time + 1.0;
spawnRate = 1000;
bounceFactor = 0.0;
spawnLife = 1.0;
scaleRate = 1.0;
velocity = vec_zero;
offset = vec_zero;
spinRate = 0.0;
scale = 1.0;
fadeIn = 0.0;
fadeDelay = spawnLife;
maxAlpha = 1.0;
lastSpawnTime = level.inttime + 150;
}
void SmokeGrenade::Think()
{
if (level.time >= nextRemoveTime) {
Delete();
return;
}
if (level.inttime >= lastSpawnTime + spawnRate) {
SmokeSprite sp;
float degrees;
lastSpawnTime += spawnRate;
sp.origin = origin;
sp.spawnTime = level.time;
sp.scale = scale;
degrees = angles.y + (((level.inttime / 1000.0 - 176.0) * spinRate) * -0.36);
RotatePointAroundAxis(sp.velocity, 2, velocity, degrees);
sp.spawnLife = spawnLife;
sp.bounceFactor = bounceFactor;
sp.scaleStart = scale;
sp.scaleRate = scaleRate;
sp.fadeIn = fadeIn;
sp.fadeDelay = fadeDelay;
sp.maxAlpha = maxAlpha;
sp.owner = owner;
G_AddSmokeSprite(&sp);
}
}
2023-10-03 18:30:19 +02:00
void SmokeGrenade::Archive(Archiver& arc)
{
EffectEntity::Archive(arc);
arc.ArchiveFloat(&nextRemoveTime);
arc.ArchiveInteger(&spawnRate);
arc.ArchiveFloat(&bounceFactor);
arc.ArchiveFloat(&spawnLife);
arc.ArchiveFloat(&scaleRate);
arc.ArchiveVector(&velocity);
arc.ArchiveFloat(&spinRate);
arc.ArchiveVector(&offset);
arc.ArchiveFloat(&scale);
arc.ArchiveFloat(&fadeIn);
arc.ArchiveFloat(&fadeDelay);
arc.ArchiveFloat(&maxAlpha);
arc.ArchiveInteger(&lastSpawnTime);
arc.ArchiveSafePointer(&owner);
}
void SmokeGrenade::setOwner(Sentient *other)
2023-10-03 18:30:19 +02:00
{
owner = other;
}
Sentient *SmokeGrenade::getOwner() const
2023-10-03 18:30:19 +02:00
{
return owner;
}