2008-01-27 11:25:03 +00:00
|
|
|
/*
|
|
|
|
** p_effect.cpp
|
|
|
|
** Particle effects
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 1998-2006 Randy Heit
|
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
|
|
** documentation and/or other materials provided with the distribution.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
** If particles used real sprites instead of blocks, they could be much
|
|
|
|
** more useful.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "doomtype.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "actor.h"
|
|
|
|
#include "p_effect.h"
|
|
|
|
#include "p_local.h"
|
|
|
|
#include "g_level.h"
|
|
|
|
#include "v_video.h"
|
|
|
|
#include "m_random.h"
|
|
|
|
#include "r_defs.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "templates.h"
|
2008-09-01 19:08:19 +00:00
|
|
|
#include "gi.h"
|
2008-09-15 23:47:00 +00:00
|
|
|
#include "v_palette.h"
|
|
|
|
#include "colormatcher.h"
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
|
2009-06-06 15:24:18 +00:00
|
|
|
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);
|
|
|
|
CVAR (Int, r_rail_spiralsparsity, 1, CVAR_ARCHIVE);
|
|
|
|
CVAR (Int, r_rail_trailsparsity, 1, CVAR_ARCHIVE);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
#define FADEFROMTTL(a) (255/(a))
|
|
|
|
|
|
|
|
static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black,
|
|
|
|
red1, green1, blue1, yellow1, purple, purple1, white,
|
|
|
|
rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5,
|
2008-09-01 19:08:19 +00:00
|
|
|
maroon1, maroon2, blood1, blood2;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
static const struct ColorList {
|
|
|
|
int *color;
|
|
|
|
BYTE r, g, b;
|
|
|
|
} Colors[] = {
|
|
|
|
{&grey1, 85, 85, 85 },
|
|
|
|
{&grey2, 171, 171, 171},
|
|
|
|
{&grey3, 50, 50, 50 },
|
|
|
|
{&grey4, 210, 210, 210},
|
|
|
|
{&grey5, 128, 128, 128},
|
|
|
|
{&red, 255, 0, 0 },
|
|
|
|
{&green, 0, 200, 0 },
|
|
|
|
{&blue, 0, 0, 255},
|
|
|
|
{&yellow, 255, 255, 0 },
|
|
|
|
{&black, 0, 0, 0 },
|
|
|
|
{&red1, 255, 127, 127},
|
|
|
|
{&green1, 127, 255, 127},
|
|
|
|
{&blue1, 127, 127, 255},
|
|
|
|
{&yellow1, 255, 255, 180},
|
|
|
|
{&purple, 120, 0, 160},
|
|
|
|
{&purple1, 200, 30, 255},
|
|
|
|
{&white, 255, 255, 255},
|
|
|
|
{&rblue1, 81, 81, 255},
|
|
|
|
{&rblue2, 0, 0, 227},
|
|
|
|
{&rblue3, 0, 0, 130},
|
|
|
|
{&rblue4, 0, 0, 80 },
|
|
|
|
{&orange, 255, 120, 0 },
|
|
|
|
{&yorange, 255, 170, 0 },
|
|
|
|
{&dred, 80, 0, 0 },
|
|
|
|
{&maroon1, 154, 49, 49 },
|
|
|
|
{&maroon2, 125, 24, 24 },
|
2011-02-20 11:58:37 +00:00
|
|
|
{NULL, 0, 0, 0 }
|
2008-01-27 11:25:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void P_InitEffects ()
|
|
|
|
{
|
|
|
|
const struct ColorList *color = Colors;
|
|
|
|
|
|
|
|
while (color->color)
|
|
|
|
{
|
|
|
|
*(color->color) = ColorMatcher.Pick (color->r, color->g, color->b);
|
|
|
|
color++;
|
|
|
|
}
|
2008-09-01 19:08:19 +00:00
|
|
|
|
2008-09-04 14:15:27 +00:00
|
|
|
int kind = gameinfo.defaultbloodparticlecolor;
|
2008-09-01 19:08:19 +00:00
|
|
|
blood1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind));
|
|
|
|
blood2 = ColorMatcher.Pick(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
2008-09-01 19:08:19 +00:00
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
void P_ThinkParticles ()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
particle_t *particle, *prev;
|
|
|
|
|
|
|
|
i = ActiveParticles;
|
|
|
|
prev = NULL;
|
|
|
|
while (i != NO_PARTICLE)
|
|
|
|
{
|
|
|
|
BYTE oldtrans;
|
|
|
|
|
|
|
|
particle = Particles + i;
|
|
|
|
i = particle->tnext;
|
|
|
|
oldtrans = particle->trans;
|
|
|
|
particle->trans -= particle->fade;
|
|
|
|
if (oldtrans < particle->trans || --particle->ttl == 0)
|
|
|
|
{ // The particle has expired, so free it
|
|
|
|
memset (particle, 0, sizeof(particle_t));
|
|
|
|
if (prev)
|
|
|
|
prev->tnext = i;
|
|
|
|
else
|
|
|
|
ActiveParticles = i;
|
|
|
|
particle->tnext = InactiveParticles;
|
|
|
|
InactiveParticles = (int)(particle - Particles);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
particle->x += particle->velx;
|
|
|
|
particle->y += particle->vely;
|
|
|
|
particle->z += particle->velz;
|
|
|
|
particle->velx += particle->accx;
|
|
|
|
particle->vely += particle->accy;
|
|
|
|
particle->velz += particle->accz;
|
|
|
|
prev = particle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// P_RunEffects
|
|
|
|
//
|
|
|
|
// Run effects on all actors in the world
|
|
|
|
//
|
|
|
|
void P_RunEffects ()
|
|
|
|
{
|
|
|
|
if (players[consoleplayer].camera == NULL) return;
|
|
|
|
|
|
|
|
int pnum = int(players[consoleplayer].camera->Sector - sectors) * numsectors;
|
|
|
|
|
|
|
|
AActor *actor;
|
|
|
|
TThinkerIterator<AActor> iterator;
|
|
|
|
|
|
|
|
while ( (actor = iterator.Next ()) )
|
|
|
|
{
|
|
|
|
if (actor->effects)
|
|
|
|
{
|
|
|
|
// Only run the effect if the actor is potentially visible
|
|
|
|
int rnum = pnum + int(actor->Sector - sectors);
|
|
|
|
if (rejectmatrix == NULL || !(rejectmatrix[rnum>>3] & (1 << (rnum & 7))))
|
|
|
|
P_RunEffect (actor, actor->effects);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// AddParticle
|
|
|
|
//
|
|
|
|
// Creates a particle with "jitter"
|
|
|
|
//
|
|
|
|
particle_t *JitterParticle (int ttl)
|
|
|
|
{
|
|
|
|
particle_t *particle = NewParticle ();
|
|
|
|
|
|
|
|
if (particle) {
|
|
|
|
fixed_t *val = &particle->velx;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// Set initial velocities
|
|
|
|
for (i = 3; i; i--, val++)
|
|
|
|
*val = (FRACUNIT/4096) * (M_Random () - 128);
|
|
|
|
// Set initial accelerations
|
|
|
|
for (i = 3; i; i--, val++)
|
|
|
|
*val = (FRACUNIT/16384) * (M_Random () - 128);
|
|
|
|
|
|
|
|
particle->trans = 255; // fully opaque
|
|
|
|
particle->ttl = ttl;
|
|
|
|
particle->fade = FADEFROMTTL(ttl);
|
|
|
|
}
|
|
|
|
return particle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void MakeFountain (AActor *actor, int color1, int color2)
|
|
|
|
{
|
|
|
|
particle_t *particle;
|
|
|
|
|
|
|
|
if (!(level.time & 1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
particle = JitterParticle (51);
|
|
|
|
|
|
|
|
if (particle)
|
|
|
|
{
|
|
|
|
angle_t an = M_Random()<<(24-ANGLETOFINESHIFT);
|
|
|
|
fixed_t out = FixedMul (actor->radius, M_Random()<<8);
|
|
|
|
|
|
|
|
particle->x = actor->x + FixedMul (out, finecosine[an]);
|
|
|
|
particle->y = actor->y + FixedMul (out, finesine[an]);
|
|
|
|
particle->z = actor->z + actor->height + FRACUNIT;
|
|
|
|
if (out < actor->radius/8)
|
|
|
|
particle->velz += FRACUNIT*10/3;
|
|
|
|
else
|
|
|
|
particle->velz += FRACUNIT*3;
|
|
|
|
particle->accz -= FRACUNIT/11;
|
|
|
|
if (M_Random() < 30) {
|
|
|
|
particle->size = 4;
|
|
|
|
particle->color = color2;
|
|
|
|
} else {
|
|
|
|
particle->size = 6;
|
|
|
|
particle->color = color1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void P_RunEffect (AActor *actor, int effects)
|
|
|
|
{
|
2010-01-30 14:54:56 +00:00
|
|
|
angle_t moveangle;
|
|
|
|
|
|
|
|
// 512 is the limit below which R_PointToAngle2 does no longer returns usable values.
|
|
|
|
if (abs(actor->velx) > 512 || abs(actor->vely) > 512)
|
|
|
|
{
|
|
|
|
moveangle = R_PointToAngle2(0,0,actor->velx,actor->vely);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
moveangle = actor->angle;
|
|
|
|
}
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
particle_t *particle;
|
|
|
|
int i;
|
|
|
|
|
- Fixed: The players were not added to FS's list of spawned things.
- Update to ZDoom r882
- Added the option to use $ as a prefix to a string table name everywhere in
MAPINFO where 'lookup' could be specified so that there is one consistent
way to do it.
- Externalized all default episode definitions. Added an 'optional' keyword
to handle M4 and 5 in Doom and Heretic.
- Added P_CheckMapData function and replaced all calls to P_OpenMapData that
only checked for a map's presence with it.
- Added Martin Howe's player statusbar face submission.
- Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap'
but keeps all existing information in the default and just adds to it. This
is needed because Hexen and Strife set some information in their base
MAPINFO and using 'defaultmap' in a PWAD would override that.
- Fixed: Using MAPINFO's f1 option could cause memory leaks.
- Added option to load lumps by full name to several places:
* Finale texts loaded from a text lump
* Demos
* Local SNDINFOs
* Local SNDSEQs
* Image names in FONTDEFS
* intermission script names
- Changed the STCFN121 handling. The character is not an 'I' but a '|' so
instead of discarding it it should be inserted at position 124.
- Renamed indexfont.fon to indexfont so that I could remove a special case
from V_GetFont that was just added for this one font.
- Added a 'dumpspawnedthings' CVAR that enables a listing of all things in
the map and the actor type they spawned.
SBarInfo Update #16
- Added: fillzeros flag for drawnumber. When set the string will always have
a length of the specified size and zeros will fill in for the missing places.
If the number is negative the negative sign will take the place of the last
digit.
- Added: globalarray type to drawnumber which will display the value in a
global array with the index set to the player's number. Untested.
- Added: isselected command to SBarInfo.
- Fixed: Bi and Tri colored numbers didn't work.
- Fixed: Crash when using nullimage as the last image in drawswitchableimage.
- Applied Graf suggestion to include the y coord when calulating heights to fix
most of the gaps caused by round off errors. At least for now anyways and it
is only applied for drawimage.
- SBarInfo inventory bars have been converted to use screen->DrawTexture()
- Increased limit for demon/melee to 4.
- Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided
line.
- Fixed: P_SpawnPuff assumed that all melee attacks have the same range
(MELEERANGE) and didn't set the puff to its melee state if the range
was different. Even worse, it checked a global variable for this so
the behavior was undefined when P_SpawnPuff was called from anywhere
else but P_LineAttack. To reduce the amount of parameters I combined
this information with the hitthing and temporary parameters into one
flags parameter. Also changed P_LineAttack so that it gets passed
an additional parameter that specifies whether the attack is a melee
attack or not and set this to true in all calls that are to be considered
melee attacks. I couldn't use the damage type because A_CustomPunch
and A_CustomMeleeAttack allow passing any damage type they want.
- Added a sprite option as an alternative of particles for FX_ROCKET
and FX_GRENADE.
- Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for
DECORATE was wrong (2 instead of 1.)
- Changed: Hexen set every cluster to be a hub if it hadn't been defined before
a level using this cluster. Now it will only do that if HexenHack is true,
i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format
MAPINFOs it will now be the same as for the other games which means that
'hub' has to be declared explicitly.
- Added an Idle state that is entered in place of the spawn state if a monster
has to return to its inactive state if it can't find any more targets.
- Added MF5_NOINTERACTION flag which completely disables all physics related
code for any actor with this flag. Mostly useful for particle effects where
the actors just move a certain distance and then disappear.
- Removed the last remains of the antialias precalculation code from
am_map.cpp because it was no longer used.
- Fixed: Two-sided lines bordering a secret sector were not drawn in the
proper color
- Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color.
- Switched sounds local to the listener from head-relative 3D sounds to 2D
sounds so stereo sounds have full separation. I tried using set3DSpread,
but that still caused some blending of the channels.
- Changed FScanner so that opening a lump gives the complete wad+lump name
rather than a generic one, so identifying errors among files that all have
the same lump name no longer involves any degree of guesswork in
determining exactly which file the error occurred in.
- Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final
sequences.
- Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL
pointer checks, in case an improper sequence was encountered during
parsing but not early enough to avoid creating a slot for it in the array.
- Added support for dumping from RAW/DRO/IMF files, so now anything that
can be played as OPL can also be dumped.
- Removed the opl_enable cvar, since OPL playback is now selectable as just
another MIDI device.
- Added support for DRO playback and dual-chip RAW playback.
- Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with
MUSSong2 works just as well. There are still lots of leftover bits in
the class that should probably be removed at some point, too.
- Added dual-chip dumping support for the RAW format.
- Added DosBox Raw OPL (.DRO) dumping support. For whatever reason,
in_adlib calculates the song length for this format wrong, even though
the exact length is stored right in the header. (But in_adlib seems buggy
in general; too bad it's the only Windows version of Adplug that seems to
exist.)
- Rewrote the OPL dumper to work with MIDI as well as MUS.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
|
|
|
if ((effects & FX_ROCKET) && (cl_rockettrails & 1))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
// Rocket trail
|
|
|
|
|
|
|
|
fixed_t backx = actor->x - FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2);
|
|
|
|
fixed_t backy = actor->y - FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2);
|
Update to ZDoom r1705:
- ZDoom now disables the input method editor, since it has no east-Asian
support, and having it open a composition window when you're only expecting
a single keypress is not so good.
- Fixed: Setting intermissioncounter to false in gameinfo drew all the stats
at once, instead of revealing them one line at a time.
- Fixed: The border definition in MAPINFO's gameinfo block used extra braces.
- Added A_SetCrosshair.
- Added A_WeaponBob.
- Dropped the Hexen player classes' JumpZ down to 9, since the original value
now works as it originally did.
- MF2_NODMGTHRUST now works with players, too. (Previously, it was only for
missiles.) Also added PPF_NOTHRUSTWHILEINVUL to prevent invulnerable players
from being thrusted while taking damage. (Non-players were already
unthrusted.)
- A_ZoomFactor now scales turning with the FOV by default. ZOOM_NOSCALETURNING
will leave it unaltered.
- Added Gez's PowerInvisibility changes.
- Fixed: clearflags did not clear flags6.
- Added A_SetAngle, A_SetPitch, A_ScaleVelocity, and A_ChangeVelocity.
- Enough with this "momentum" garbage. What Doom calls "momentum" is really
velocity, and now it's known as such. The actor variables momx/momy/momz
are now known as velx/vely/velz, and the ACS functions GetActorMomX/Y/Z
are now known as GetActorVelX/Y/Z. For compatibility, momx/momy/momz will
continue to work as aliases from DECORATE. The ACS functions, however,
require you to use the new name, since they never saw an official release
yet.
- Added A_ZoomFactor. This lets weapons scale their player's FOV. Each weapon
maintains its own FOV scale independent from any other weapons the player
may have.
- Fixed: When parsing DECORATE functions that were not exported, the parser
crashed after giving you the warning.
- Fixed some improper preprocessor lines in autostart/autozend.cpp.
- Added XInput support. For the benefit of people compiling with MinGW,
the CMakeLists.txt checks for xinput.h and disables it if it cannot
be found. (And much to my surprise, I accidentally discovered that if you
have the DirectX SDK installed, those headers actually do work with GCC,
though they add a few extra warnings.)
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@376 b0f79afe-0144-0410-b225-9a4edf0717df
2009-07-04 08:28:50 +00:00
|
|
|
fixed_t backz = actor->z - (actor->height>>3) * (actor->velz>>16) + (2*actor->height)/3;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
angle_t an = (moveangle + ANG90) >> ANGLETOFINESHIFT;
|
|
|
|
int speed;
|
|
|
|
|
|
|
|
particle = JitterParticle (3 + (M_Random() & 31));
|
|
|
|
if (particle) {
|
|
|
|
fixed_t pathdist = M_Random()<<8;
|
Update to ZDoom r1705:
- ZDoom now disables the input method editor, since it has no east-Asian
support, and having it open a composition window when you're only expecting
a single keypress is not so good.
- Fixed: Setting intermissioncounter to false in gameinfo drew all the stats
at once, instead of revealing them one line at a time.
- Fixed: The border definition in MAPINFO's gameinfo block used extra braces.
- Added A_SetCrosshair.
- Added A_WeaponBob.
- Dropped the Hexen player classes' JumpZ down to 9, since the original value
now works as it originally did.
- MF2_NODMGTHRUST now works with players, too. (Previously, it was only for
missiles.) Also added PPF_NOTHRUSTWHILEINVUL to prevent invulnerable players
from being thrusted while taking damage. (Non-players were already
unthrusted.)
- A_ZoomFactor now scales turning with the FOV by default. ZOOM_NOSCALETURNING
will leave it unaltered.
- Added Gez's PowerInvisibility changes.
- Fixed: clearflags did not clear flags6.
- Added A_SetAngle, A_SetPitch, A_ScaleVelocity, and A_ChangeVelocity.
- Enough with this "momentum" garbage. What Doom calls "momentum" is really
velocity, and now it's known as such. The actor variables momx/momy/momz
are now known as velx/vely/velz, and the ACS functions GetActorMomX/Y/Z
are now known as GetActorVelX/Y/Z. For compatibility, momx/momy/momz will
continue to work as aliases from DECORATE. The ACS functions, however,
require you to use the new name, since they never saw an official release
yet.
- Added A_ZoomFactor. This lets weapons scale their player's FOV. Each weapon
maintains its own FOV scale independent from any other weapons the player
may have.
- Fixed: When parsing DECORATE functions that were not exported, the parser
crashed after giving you the warning.
- Fixed some improper preprocessor lines in autostart/autozend.cpp.
- Added XInput support. For the benefit of people compiling with MinGW,
the CMakeLists.txt checks for xinput.h and disables it if it cannot
be found. (And much to my surprise, I accidentally discovered that if you
have the DirectX SDK installed, those headers actually do work with GCC,
though they add a few extra warnings.)
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@376 b0f79afe-0144-0410-b225-9a4edf0717df
2009-07-04 08:28:50 +00:00
|
|
|
particle->x = backx - FixedMul(actor->velx, pathdist);
|
|
|
|
particle->y = backy - FixedMul(actor->vely, pathdist);
|
|
|
|
particle->z = backz - FixedMul(actor->velz, pathdist);
|
2008-01-27 11:25:03 +00:00
|
|
|
speed = (M_Random () - 128) * (FRACUNIT/200);
|
|
|
|
particle->velx += FixedMul (speed, finecosine[an]);
|
|
|
|
particle->vely += FixedMul (speed, finesine[an]);
|
|
|
|
particle->velz -= FRACUNIT/36;
|
|
|
|
particle->accz -= FRACUNIT/20;
|
|
|
|
particle->color = yellow;
|
|
|
|
particle->size = 2;
|
|
|
|
}
|
|
|
|
for (i = 6; i; i--) {
|
|
|
|
particle_t *particle = JitterParticle (3 + (M_Random() & 31));
|
|
|
|
if (particle) {
|
|
|
|
fixed_t pathdist = M_Random()<<8;
|
Update to ZDoom r1705:
- ZDoom now disables the input method editor, since it has no east-Asian
support, and having it open a composition window when you're only expecting
a single keypress is not so good.
- Fixed: Setting intermissioncounter to false in gameinfo drew all the stats
at once, instead of revealing them one line at a time.
- Fixed: The border definition in MAPINFO's gameinfo block used extra braces.
- Added A_SetCrosshair.
- Added A_WeaponBob.
- Dropped the Hexen player classes' JumpZ down to 9, since the original value
now works as it originally did.
- MF2_NODMGTHRUST now works with players, too. (Previously, it was only for
missiles.) Also added PPF_NOTHRUSTWHILEINVUL to prevent invulnerable players
from being thrusted while taking damage. (Non-players were already
unthrusted.)
- A_ZoomFactor now scales turning with the FOV by default. ZOOM_NOSCALETURNING
will leave it unaltered.
- Added Gez's PowerInvisibility changes.
- Fixed: clearflags did not clear flags6.
- Added A_SetAngle, A_SetPitch, A_ScaleVelocity, and A_ChangeVelocity.
- Enough with this "momentum" garbage. What Doom calls "momentum" is really
velocity, and now it's known as such. The actor variables momx/momy/momz
are now known as velx/vely/velz, and the ACS functions GetActorMomX/Y/Z
are now known as GetActorVelX/Y/Z. For compatibility, momx/momy/momz will
continue to work as aliases from DECORATE. The ACS functions, however,
require you to use the new name, since they never saw an official release
yet.
- Added A_ZoomFactor. This lets weapons scale their player's FOV. Each weapon
maintains its own FOV scale independent from any other weapons the player
may have.
- Fixed: When parsing DECORATE functions that were not exported, the parser
crashed after giving you the warning.
- Fixed some improper preprocessor lines in autostart/autozend.cpp.
- Added XInput support. For the benefit of people compiling with MinGW,
the CMakeLists.txt checks for xinput.h and disables it if it cannot
be found. (And much to my surprise, I accidentally discovered that if you
have the DirectX SDK installed, those headers actually do work with GCC,
though they add a few extra warnings.)
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@376 b0f79afe-0144-0410-b225-9a4edf0717df
2009-07-04 08:28:50 +00:00
|
|
|
particle->x = backx - FixedMul(actor->velx, pathdist);
|
|
|
|
particle->y = backy - FixedMul(actor->vely, pathdist);
|
|
|
|
particle->z = backz - FixedMul(actor->velz, pathdist) + (M_Random() << 10);
|
2008-01-27 11:25:03 +00:00
|
|
|
speed = (M_Random () - 128) * (FRACUNIT/200);
|
|
|
|
particle->velx += FixedMul (speed, finecosine[an]);
|
|
|
|
particle->vely += FixedMul (speed, finesine[an]);
|
|
|
|
particle->velz += FRACUNIT/80;
|
|
|
|
particle->accz += FRACUNIT/40;
|
|
|
|
if (M_Random () & 7)
|
|
|
|
particle->color = grey2;
|
|
|
|
else
|
|
|
|
particle->color = grey1;
|
|
|
|
particle->size = 3;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
- Fixed: The players were not added to FS's list of spawned things.
- Update to ZDoom r882
- Added the option to use $ as a prefix to a string table name everywhere in
MAPINFO where 'lookup' could be specified so that there is one consistent
way to do it.
- Externalized all default episode definitions. Added an 'optional' keyword
to handle M4 and 5 in Doom and Heretic.
- Added P_CheckMapData function and replaced all calls to P_OpenMapData that
only checked for a map's presence with it.
- Added Martin Howe's player statusbar face submission.
- Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap'
but keeps all existing information in the default and just adds to it. This
is needed because Hexen and Strife set some information in their base
MAPINFO and using 'defaultmap' in a PWAD would override that.
- Fixed: Using MAPINFO's f1 option could cause memory leaks.
- Added option to load lumps by full name to several places:
* Finale texts loaded from a text lump
* Demos
* Local SNDINFOs
* Local SNDSEQs
* Image names in FONTDEFS
* intermission script names
- Changed the STCFN121 handling. The character is not an 'I' but a '|' so
instead of discarding it it should be inserted at position 124.
- Renamed indexfont.fon to indexfont so that I could remove a special case
from V_GetFont that was just added for this one font.
- Added a 'dumpspawnedthings' CVAR that enables a listing of all things in
the map and the actor type they spawned.
SBarInfo Update #16
- Added: fillzeros flag for drawnumber. When set the string will always have
a length of the specified size and zeros will fill in for the missing places.
If the number is negative the negative sign will take the place of the last
digit.
- Added: globalarray type to drawnumber which will display the value in a
global array with the index set to the player's number. Untested.
- Added: isselected command to SBarInfo.
- Fixed: Bi and Tri colored numbers didn't work.
- Fixed: Crash when using nullimage as the last image in drawswitchableimage.
- Applied Graf suggestion to include the y coord when calulating heights to fix
most of the gaps caused by round off errors. At least for now anyways and it
is only applied for drawimage.
- SBarInfo inventory bars have been converted to use screen->DrawTexture()
- Increased limit for demon/melee to 4.
- Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided
line.
- Fixed: P_SpawnPuff assumed that all melee attacks have the same range
(MELEERANGE) and didn't set the puff to its melee state if the range
was different. Even worse, it checked a global variable for this so
the behavior was undefined when P_SpawnPuff was called from anywhere
else but P_LineAttack. To reduce the amount of parameters I combined
this information with the hitthing and temporary parameters into one
flags parameter. Also changed P_LineAttack so that it gets passed
an additional parameter that specifies whether the attack is a melee
attack or not and set this to true in all calls that are to be considered
melee attacks. I couldn't use the damage type because A_CustomPunch
and A_CustomMeleeAttack allow passing any damage type they want.
- Added a sprite option as an alternative of particles for FX_ROCKET
and FX_GRENADE.
- Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for
DECORATE was wrong (2 instead of 1.)
- Changed: Hexen set every cluster to be a hub if it hadn't been defined before
a level using this cluster. Now it will only do that if HexenHack is true,
i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format
MAPINFOs it will now be the same as for the other games which means that
'hub' has to be declared explicitly.
- Added an Idle state that is entered in place of the spawn state if a monster
has to return to its inactive state if it can't find any more targets.
- Added MF5_NOINTERACTION flag which completely disables all physics related
code for any actor with this flag. Mostly useful for particle effects where
the actors just move a certain distance and then disappear.
- Removed the last remains of the antialias precalculation code from
am_map.cpp because it was no longer used.
- Fixed: Two-sided lines bordering a secret sector were not drawn in the
proper color
- Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color.
- Switched sounds local to the listener from head-relative 3D sounds to 2D
sounds so stereo sounds have full separation. I tried using set3DSpread,
but that still caused some blending of the channels.
- Changed FScanner so that opening a lump gives the complete wad+lump name
rather than a generic one, so identifying errors among files that all have
the same lump name no longer involves any degree of guesswork in
determining exactly which file the error occurred in.
- Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final
sequences.
- Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL
pointer checks, in case an improper sequence was encountered during
parsing but not early enough to avoid creating a slot for it in the array.
- Added support for dumping from RAW/DRO/IMF files, so now anything that
can be played as OPL can also be dumped.
- Removed the opl_enable cvar, since OPL playback is now selectable as just
another MIDI device.
- Added support for DRO playback and dual-chip RAW playback.
- Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with
MUSSong2 works just as well. There are still lots of leftover bits in
the class that should probably be removed at some point, too.
- Added dual-chip dumping support for the RAW format.
- Added DosBox Raw OPL (.DRO) dumping support. For whatever reason,
in_adlib calculates the song length for this format wrong, even though
the exact length is stored right in the header. (But in_adlib seems buggy
in general; too bad it's the only Windows version of Adplug that seems to
exist.)
- Rewrote the OPL dumper to work with MIDI as well as MUS.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
|
|
|
if ((effects & FX_GRENADE) && (cl_rockettrails & 1))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
// Grenade trail
|
|
|
|
|
|
|
|
P_DrawSplash2 (6,
|
|
|
|
actor->x - FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2),
|
|
|
|
actor->y - FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2),
|
Update to ZDoom r1705:
- ZDoom now disables the input method editor, since it has no east-Asian
support, and having it open a composition window when you're only expecting
a single keypress is not so good.
- Fixed: Setting intermissioncounter to false in gameinfo drew all the stats
at once, instead of revealing them one line at a time.
- Fixed: The border definition in MAPINFO's gameinfo block used extra braces.
- Added A_SetCrosshair.
- Added A_WeaponBob.
- Dropped the Hexen player classes' JumpZ down to 9, since the original value
now works as it originally did.
- MF2_NODMGTHRUST now works with players, too. (Previously, it was only for
missiles.) Also added PPF_NOTHRUSTWHILEINVUL to prevent invulnerable players
from being thrusted while taking damage. (Non-players were already
unthrusted.)
- A_ZoomFactor now scales turning with the FOV by default. ZOOM_NOSCALETURNING
will leave it unaltered.
- Added Gez's PowerInvisibility changes.
- Fixed: clearflags did not clear flags6.
- Added A_SetAngle, A_SetPitch, A_ScaleVelocity, and A_ChangeVelocity.
- Enough with this "momentum" garbage. What Doom calls "momentum" is really
velocity, and now it's known as such. The actor variables momx/momy/momz
are now known as velx/vely/velz, and the ACS functions GetActorMomX/Y/Z
are now known as GetActorVelX/Y/Z. For compatibility, momx/momy/momz will
continue to work as aliases from DECORATE. The ACS functions, however,
require you to use the new name, since they never saw an official release
yet.
- Added A_ZoomFactor. This lets weapons scale their player's FOV. Each weapon
maintains its own FOV scale independent from any other weapons the player
may have.
- Fixed: When parsing DECORATE functions that were not exported, the parser
crashed after giving you the warning.
- Fixed some improper preprocessor lines in autostart/autozend.cpp.
- Added XInput support. For the benefit of people compiling with MinGW,
the CMakeLists.txt checks for xinput.h and disables it if it cannot
be found. (And much to my surprise, I accidentally discovered that if you
have the DirectX SDK installed, those headers actually do work with GCC,
though they add a few extra warnings.)
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@376 b0f79afe-0144-0410-b225-9a4edf0717df
2009-07-04 08:28:50 +00:00
|
|
|
actor->z - (actor->height>>3) * (actor->velz>>16) + (2*actor->height)/3,
|
2008-01-27 11:25:03 +00:00
|
|
|
moveangle + ANG180, 2, 2);
|
|
|
|
}
|
|
|
|
if (effects & FX_FOUNTAINMASK)
|
|
|
|
{
|
|
|
|
// Particle fountain
|
|
|
|
|
|
|
|
static const int *fountainColors[16] =
|
|
|
|
{ &black, &black,
|
|
|
|
&red, &red1,
|
|
|
|
&green, &green1,
|
|
|
|
&blue, &blue1,
|
|
|
|
&yellow, &yellow1,
|
|
|
|
&purple, &purple1,
|
|
|
|
&black, &grey3,
|
|
|
|
&grey4, &white
|
|
|
|
};
|
|
|
|
int color = (effects & FX_FOUNTAINMASK) >> 15;
|
|
|
|
MakeFountain (actor, *fountainColors[color], *fountainColors[color+1]);
|
|
|
|
}
|
|
|
|
if (effects & FX_RESPAWNINVUL)
|
|
|
|
{
|
|
|
|
// Respawn protection
|
|
|
|
|
|
|
|
static const int *protectColors[2] = { &yellow1, &white };
|
|
|
|
|
|
|
|
for (i = 3; i > 0; i--)
|
|
|
|
{
|
|
|
|
particle = JitterParticle (16);
|
|
|
|
if (particle != NULL)
|
|
|
|
{
|
|
|
|
angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8);
|
|
|
|
particle->x = actor->x + FixedMul (actor->radius, finecosine[ang]);
|
|
|
|
particle->y = actor->y + FixedMul (actor->radius, finesine[ang]);
|
|
|
|
particle->color = *protectColors[M_Random() & 1];
|
|
|
|
particle->z = actor->z;
|
|
|
|
particle->velz = FRACUNIT;
|
|
|
|
particle->accz = M_Random () << 7;
|
|
|
|
particle->size = 1;
|
|
|
|
if (M_Random () < 128)
|
|
|
|
{ // make particle fall from top of actor
|
|
|
|
particle->z += actor->height;
|
|
|
|
particle->velz = -particle->velz;
|
|
|
|
particle->accz = -particle->accz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind)
|
|
|
|
{
|
|
|
|
int color1, color2;
|
|
|
|
|
|
|
|
switch (kind)
|
|
|
|
{
|
|
|
|
case 1: // Spark
|
|
|
|
color1 = orange;
|
|
|
|
color2 = yorange;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; count; count--)
|
|
|
|
{
|
|
|
|
particle_t *p = JitterParticle (10);
|
|
|
|
angle_t an;
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
break;
|
|
|
|
|
|
|
|
p->size = 2;
|
|
|
|
p->color = M_Random() & 0x80 ? color1 : color2;
|
|
|
|
p->velz -= M_Random () * 512;
|
|
|
|
p->accz -= FRACUNIT/8;
|
|
|
|
p->accx += (M_Random () - 128) * 8;
|
|
|
|
p->accy += (M_Random () - 128) * 8;
|
|
|
|
p->z = z - M_Random () * 1024;
|
|
|
|
an = (angle + (M_Random() << 21)) >> ANGLETOFINESHIFT;
|
|
|
|
p->x = x + (M_Random () & 15)*finecosine[an];
|
|
|
|
p->y = y + (M_Random () & 15)*finesine[an];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind)
|
|
|
|
{
|
|
|
|
int color1, color2, zvel, zspread, zadd;
|
|
|
|
|
|
|
|
switch (kind)
|
|
|
|
{
|
|
|
|
case 0: // Blood
|
2008-09-01 19:08:19 +00:00
|
|
|
color1 = blood1;
|
|
|
|
color2 = blood2;
|
2008-01-27 11:25:03 +00:00
|
|
|
break;
|
|
|
|
case 1: // Gunshot
|
|
|
|
color1 = grey3;
|
|
|
|
color2 = grey5;
|
|
|
|
break;
|
|
|
|
case 2: // Smoke
|
|
|
|
color1 = grey3;
|
|
|
|
color2 = grey1;
|
|
|
|
break;
|
|
|
|
default: // colorized blood
|
|
|
|
color1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind));
|
|
|
|
color2 = ColorMatcher.Pick(RPART(kind)>>1, GPART(kind)>>1, BPART(kind)>>1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
zvel = -128;
|
|
|
|
zspread = updown ? -6000 : 6000;
|
|
|
|
zadd = (updown == 2) ? -128 : 0;
|
|
|
|
|
|
|
|
for (; count; count--)
|
|
|
|
{
|
|
|
|
particle_t *p = NewParticle ();
|
|
|
|
angle_t an;
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
break;
|
|
|
|
|
|
|
|
p->ttl = 12;
|
|
|
|
p->fade = FADEFROMTTL(12);
|
|
|
|
p->trans = 255;
|
|
|
|
p->size = 4;
|
|
|
|
p->color = M_Random() & 0x80 ? color1 : color2;
|
|
|
|
p->velz = M_Random () * zvel;
|
|
|
|
p->accz = -FRACUNIT/22;
|
|
|
|
if (kind) {
|
|
|
|
an = (angle + ((M_Random() - 128) << 23)) >> ANGLETOFINESHIFT;
|
|
|
|
p->velx = (M_Random () * finecosine[an]) >> 11;
|
|
|
|
p->vely = (M_Random () * finesine[an]) >> 11;
|
|
|
|
p->accx = p->velx >> 4;
|
|
|
|
p->accy = p->vely >> 4;
|
|
|
|
}
|
|
|
|
p->z = z + (M_Random () + zadd - 128) * zspread;
|
|
|
|
an = (angle + ((M_Random() - 128) << 22)) >> ANGLETOFINESHIFT;
|
|
|
|
p->x = x + ((M_Random () & 31)-15)*finecosine[an];
|
|
|
|
p->y = y + ((M_Random () & 31)-15)*finesine[an];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end, int color1, int color2, float maxdiff, bool silent)
|
|
|
|
{
|
|
|
|
double length, lengthsquared;
|
|
|
|
int steps, i;
|
|
|
|
FAngle deg;
|
|
|
|
FVector3 step, dir, pos, extend;
|
|
|
|
|
|
|
|
dir = end - start;
|
|
|
|
lengthsquared = dir | dir;
|
|
|
|
length = sqrt(lengthsquared);
|
|
|
|
steps = int(length / 3);
|
|
|
|
|
|
|
|
if (steps)
|
|
|
|
{
|
|
|
|
if (!silent)
|
|
|
|
{
|
2008-06-15 17:17:31 +00:00
|
|
|
FSoundID sound;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// Allow other sounds than 'weapons/railgf'!
|
|
|
|
if (!source->player) sound = source->AttackSound;
|
|
|
|
else if (source->player->ReadyWeapon) sound = source->player->ReadyWeapon->AttackSound;
|
|
|
|
else sound = 0;
|
2008-06-15 17:17:31 +00:00
|
|
|
if (!sound) sound = "weapons/railgf";
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// The railgun's sound is special. It gets played from the
|
|
|
|
// point on the slug's trail that is closest to the hearing player.
|
|
|
|
AActor *mo = players[consoleplayer].camera;
|
|
|
|
FVector3 point;
|
|
|
|
double r;
|
|
|
|
float dirz;
|
|
|
|
|
|
|
|
if (abs(mo->x - FLOAT2FIXED(start.X)) < 20 * FRACUNIT
|
|
|
|
&& (mo->y - FLOAT2FIXED(start.Y)) < 20 * FRACUNIT)
|
|
|
|
{ // This player (probably) fired the railgun
|
2008-06-15 17:17:31 +00:00
|
|
|
S_Sound (mo, CHAN_WEAPON, sound, 1, ATTN_NORM);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-10-17 16:33:44 +00:00
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
// Only consider sound in 2D (for now, anyway)
|
|
|
|
// [BB] You have to devide by lengthsquared here, not multiply with it.
|
2009-10-17 16:33:44 +00:00
|
|
|
|
|
|
|
r = ((start.Y - FIXED2FLOAT(mo->y)) * (-dir.Y) - (start.X - FIXED2FLOAT(mo->x)) * (dir.X)) / lengthsquared;
|
|
|
|
r = clamp<double>(r, 0., 1.);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
dirz = dir.Z;
|
|
|
|
dir.Z = 0;
|
|
|
|
point = start + r * dir;
|
|
|
|
dir.Z = dirz;
|
|
|
|
|
2009-10-17 16:33:44 +00:00
|
|
|
S_Sound (FLOAT2FIXED(point.X), FLOAT2FIXED(point.Y), viewz,
|
2008-01-27 11:25:03 +00:00
|
|
|
CHAN_WEAPON, sound, 1, ATTN_NORM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// line is 0 length, so nothing to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dir /= length;
|
|
|
|
|
|
|
|
//Calculate PerpendicularVector (extend, dir):
|
|
|
|
double minelem = 1;
|
|
|
|
int epos;
|
|
|
|
for (epos = 0, i = 0; i < 3; ++i)
|
|
|
|
{
|
|
|
|
if (fabs(dir[i]) < minelem)
|
|
|
|
{
|
|
|
|
epos = i;
|
|
|
|
minelem = fabs(dir[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FVector3 tempvec(0,0,0);
|
|
|
|
tempvec[epos] = 1;
|
|
|
|
extend = tempvec - (dir | tempvec) * dir;
|
|
|
|
//
|
|
|
|
|
|
|
|
extend *= 3;
|
|
|
|
step = dir * 3;
|
|
|
|
|
|
|
|
// Create the outer spiral.
|
2009-06-06 15:24:18 +00:00
|
|
|
if (color1 != -1 && (!r_rail_smartspiral || color2 == -1) && r_rail_spiralsparsity > 0)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2009-06-06 15:24:18 +00:00
|
|
|
FVector3 spiral_step = step * r_rail_spiralsparsity;
|
|
|
|
int spiral_steps = steps * r_rail_spiralsparsity;
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
color1 = color1 == 0 ? -1 : ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1));
|
|
|
|
pos = start;
|
|
|
|
deg = FAngle(270);
|
2009-06-06 15:24:18 +00:00
|
|
|
for (i = spiral_steps; i; i--)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
particle_t *p = NewParticle ();
|
|
|
|
FVector3 tempvec;
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
return;
|
|
|
|
|
|
|
|
p->trans = 255;
|
|
|
|
p->ttl = 35;
|
|
|
|
p->fade = FADEFROMTTL(35);
|
|
|
|
p->size = 3;
|
|
|
|
|
|
|
|
tempvec = FMatrix3x3(dir, deg) * extend;
|
|
|
|
p->velx = FLOAT2FIXED(tempvec.X)>>4;
|
|
|
|
p->vely = FLOAT2FIXED(tempvec.Y)>>4;
|
|
|
|
p->velz = FLOAT2FIXED(tempvec.Z)>>4;
|
|
|
|
tempvec += pos;
|
|
|
|
p->x = FLOAT2FIXED(tempvec.X);
|
|
|
|
p->y = FLOAT2FIXED(tempvec.Y);
|
|
|
|
p->z = FLOAT2FIXED(tempvec.Z);
|
2009-06-06 15:24:18 +00:00
|
|
|
pos += spiral_step;
|
|
|
|
deg += FAngle(r_rail_spiralsparsity * 14);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (color1 == -1)
|
|
|
|
{
|
|
|
|
int rand = M_Random();
|
|
|
|
|
|
|
|
if (rand < 155)
|
|
|
|
p->color = rblue2;
|
|
|
|
else if (rand < 188)
|
|
|
|
p->color = rblue1;
|
|
|
|
else if (rand < 222)
|
|
|
|
p->color = rblue3;
|
|
|
|
else
|
|
|
|
p->color = rblue4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->color = color1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the inner trail.
|
2009-06-06 15:24:18 +00:00
|
|
|
if (color2 != -1 && r_rail_trailsparsity > 0)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2009-06-06 15:24:18 +00:00
|
|
|
FVector3 trail_step = step * r_rail_trailsparsity;
|
|
|
|
int trail_steps = steps * r_rail_trailsparsity;
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
color2 = color2 == 0 ? -1 : ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2));
|
|
|
|
FVector3 diff(0, 0, 0);
|
|
|
|
|
|
|
|
pos = start;
|
2009-06-06 15:24:18 +00:00
|
|
|
for (i = trail_steps; i; i--)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
particle_t *p = JitterParticle (33);
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (maxdiff > 0)
|
|
|
|
{
|
|
|
|
int rnd = M_Random ();
|
|
|
|
if (rnd & 1)
|
|
|
|
diff.X = clamp<float> (diff.X + ((rnd & 8) ? 1 : -1), -maxdiff, maxdiff);
|
|
|
|
if (rnd & 2)
|
|
|
|
diff.Y = clamp<float> (diff.Y + ((rnd & 16) ? 1 : -1), -maxdiff, maxdiff);
|
|
|
|
if (rnd & 4)
|
|
|
|
diff.Z = clamp<float> (diff.Z + ((rnd & 32) ? 1 : -1), -maxdiff, maxdiff);
|
|
|
|
}
|
|
|
|
|
|
|
|
FVector3 postmp = pos + diff;
|
|
|
|
|
|
|
|
p->size = 2;
|
|
|
|
p->x = FLOAT2FIXED(postmp.X);
|
|
|
|
p->y = FLOAT2FIXED(postmp.Y);
|
|
|
|
p->z = FLOAT2FIXED(postmp.Z);
|
|
|
|
if (color1 != -1)
|
|
|
|
p->accz -= FRACUNIT/4096;
|
2009-06-06 15:24:18 +00:00
|
|
|
pos += trail_step;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (color2 == -1)
|
|
|
|
{
|
|
|
|
int rand = M_Random();
|
|
|
|
|
|
|
|
if (rand < 85)
|
|
|
|
p->color = grey4;
|
|
|
|
else if (rand < 170)
|
|
|
|
p->color = grey2;
|
|
|
|
else
|
|
|
|
p->color = grey1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->color = color2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void P_DisconnectEffect (AActor *actor)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (actor == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 64; i; i--)
|
|
|
|
{
|
|
|
|
particle_t *p = JitterParticle (TICRATE*2);
|
|
|
|
|
|
|
|
if (!p)
|
|
|
|
break;
|
|
|
|
|
|
|
|
p->x = actor->x + ((M_Random()-128)<<9) * (actor->radius>>FRACBITS);
|
|
|
|
p->y = actor->y + ((M_Random()-128)<<9) * (actor->radius>>FRACBITS);
|
|
|
|
p->z = actor->z + (M_Random()<<8) * (actor->height>>FRACBITS);
|
|
|
|
p->accz -= FRACUNIT/4096;
|
|
|
|
p->color = M_Random() < 128 ? maroon1 : maroon2;
|
|
|
|
p->size = 4;
|
|
|
|
}
|
|
|
|
}
|