- Removed ABossEye::Serialize because it didn't do anything.

- Fixed the issues with .96x's railgun code and added it to the current
  version.
- Fixed: Setting of the friendly Minotaur's angle was inconsistent and
  could cause it to move backwards in a féw situation.
- Fixed: The minotaur did checks for type by checking for the MF_FRIENDLY
  flag, not by checking for the actor class. That made it impossible to
  spawn friendly 'normal' minotaurs.
- Moved a few virtual methods which are only applicable to the friendly
  minotaur to AMinotaurFriend.
- Fixed: The friendly minotaur checked the master's health instead of
  the target's when deciding whether to switch targets. Replaced with
  MF4_NOTARGETSWITCH.
- Fixed: maybedrawnow must not draw the console unless the background
  texture has been set up.

SVN r66 (trunk)
This commit is contained in:
Christoph Oelckers 2006-04-23 20:12:27 +00:00
parent b229d07500
commit 790ff69f52
20 changed files with 312 additions and 241 deletions

View file

@ -1,4 +1,19 @@
April 22, 2006 (Changes by Graf Zahl)
- Removed ABossEye::Serialize because it didn't do anything.
- Fixed the issues with .96x's railgun code and added it to the current
version.
- Fixed: Setting of the friendly Minotaur's angle was inconsistent and
could cause it to move backwards in a féw situation.
- Fixed: The minotaur did checks for type by checking for the MF_FRIENDLY
flag, not by checking for the actor class. That made it impossible to
spawn friendly 'normal' minotaurs.
- Moved a few virtual methods which are only applicable to the friendly
minotaur to AMinotaurFriend.
- Fixed: The friendly minotaur checked the master's health instead of
the target's when deciding whether to switch targets. Replaced with
MF4_NOTARGETSWITCH.
- Fixed: maybedrawnow must not draw the console unless the background
texture has been set up.
- Fixed: V_InitCustomFonts initialized lastlump to -1 instead of 0.
- Fixed: CreateTexture never checked whether it could read from the
texture lump. Since the minimum valid length is 13 bytes for a

View file

@ -205,7 +205,7 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE)
static void maybedrawnow (bool tick, bool force)
{
if (ConsoleDrawing || screen->IsLocked ())
if (ConsoleDrawing || !gotconback || screen->IsLocked ())
{
return;
}

View file

@ -76,10 +76,11 @@ public:
{
INVUL_Start,
INVUL_Active,
INVUL_Stop
INVUL_Stop,
INVUL_GetAlpha
};
virtual void SpecialInvulnerabilityHandling (EInvulState state);
virtual void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha=NULL);
void BeginPlay ();
void Die (AActor *source, AActor *inflictor);

View file

@ -86,8 +86,6 @@ END_DEFAULTS
class ABossEye : public AActor
{
DECLARE_ACTOR (ABossEye, AActor)
public:
void Serialize (FArchive &arc);
};
FState ABossEye::States[] =
@ -108,11 +106,6 @@ IMPLEMENT_ACTOR (ABossEye, Doom, 89, 0)
PROP_SeeState (S_BRAINEYESEE)
END_DEFAULTS
void ABossEye::Serialize (FArchive &arc)
{
Super::Serialize (arc);
}
IMPLEMENT_STATELESS_ACTOR (ABossTarget, Doom, 87, 0)
PROP_HeightFixed (32)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)

View file

@ -8,6 +8,7 @@
#include "p_enemy.h"
#include "a_action.h"
#include "a_hexenglobal.h"
#include "templates.h"
// The cleric ---------------------------------------------------------------
@ -140,7 +141,7 @@ fixed_t AClericPlayer::GetJumpZ ()
return FRACUNIT*39/4; // ~9.75
}
void AClericPlayer::SpecialInvulnerabilityHandling (EInvulState state)
void AClericPlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha)
{
if (state == INVUL_Active)
{
@ -176,6 +177,10 @@ void AClericPlayer::SpecialInvulnerabilityHandling (EInvulState state)
RenderStyle = STYLE_Normal;
alpha = OPAQUE;
}
else if (state == INVUL_GetAlpha)
{
if (pAlpha != NULL) *pAlpha = MIN<fixed_t>(FRACUNIT/4 + alpha*3/4, FRACUNIT);
}
}
// Cleric Weapon Base Class -------------------------------------------------

View file

@ -105,7 +105,7 @@ public:
void GiveDefaultInventory ();
const char *GetSoundClass ();
fixed_t GetJumpZ ();
void SpecialInvulnerabilityHandling (EInvulState state);
void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha);
};
class AClericWeapon : public AWeapon
@ -125,7 +125,7 @@ public:
const char *GetSoundClass ();
fixed_t GetJumpZ ();
bool DoHealingRadius (APlayerPawn *other);
void SpecialInvulnerabilityHandling (EInvulState state);
void SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha);
};
class AMageWeapon : public AWeapon

View file

@ -173,7 +173,7 @@ bool AMagePlayer::DoHealingRadius (APlayerPawn *other)
return false;
}
void AMagePlayer::SpecialInvulnerabilityHandling (EInvulState state)
void AMagePlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * pAlpha)
{
if (state == INVUL_Start)
{
@ -183,6 +183,10 @@ void AMagePlayer::SpecialInvulnerabilityHandling (EInvulState state)
{
flags2 &= ~MF2_REFLECTIVE;
}
else if (state == INVUL_GetAlpha && pAlpha != NULL)
{
*pAlpha = FIXED_MAX;
}
}
// Mage Weapon Base Class ---------------------------------------------------

View file

@ -132,7 +132,7 @@ bool AArtiDarkServant::Use (bool pickup)
void A_Summon (AActor *actor)
{
AMinotaur *mo;
AMinotaurFriend *mo;
mo = Spawn<AMinotaurFriend> (actor->x, actor->y, actor->z);
if (mo)

View file

@ -139,24 +139,12 @@ IMPLEMENT_ACTOR (AMinotaur, Heretic, 9, 0)
PROP_ActiveSound ("minotaur/active")
END_DEFAULTS
void AMinotaur::BeginPlay ()
{
Super::BeginPlay ();
StartTime = -1;
}
void AMinotaur::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << StartTime;
}
void AMinotaur::Tick ()
{
Super::Tick ();
// The unfriendly Minotaur (Heretic's) is invulnerable while charging
if (!(flags & MF_FRIENDLY))
if (!IsKindOf(RUNTIME_CLASS(AMinotaurFriend)))
{
// Get MF_SKULLFLY bit and shift it so it matches MF2_INVULNERABLE
DWORD flying = (flags & MF_SKULLFLY) << 3;
@ -169,11 +157,8 @@ void AMinotaur::Tick ()
void AMinotaur::NoBlockingSet ()
{
if (!(flags & MF_FRIENDLY))
{
P_DropItem (this, "ArtiSuperHealth", 0, 51);
P_DropItem (this, "PhoenixRodAmmo", 10, 84);
}
P_DropItem (this, "ArtiSuperHealth", 0, 51);
P_DropItem (this, "PhoenixRodAmmo", 10, 84);
}
bool AMinotaur::Slam (AActor *thing)
@ -197,91 +182,6 @@ int AMinotaur::DoSpecialDamage (AActor *target, int damage)
return damage;
}
bool AMinotaur::IsOkayToAttack (AActor *link)
{
if ((link->flags3&MF3_ISMONSTER) && (link != tracer))
{
if (!((link->flags ^ flags) & MF_FRIENDLY))
{ // Don't attack friends
if (link->flags & MF_FRIENDLY)
{
if (!deathmatch || link->FriendPlayer == 0 || FriendPlayer == 0 ||
link->FriendPlayer != FriendPlayer)
{
return false;
}
}
else
{
return false;
}
}
if (!(link->flags&MF_SHOOTABLE))
{
return false;
}
if (link->flags2&MF2_DORMANT)
{
return false;
}
if ((link->IsKindOf (RUNTIME_CLASS(AMinotaur))) &&
(link->tracer == tracer))
{
return false;
}
if (multiplayer && !deathmatch && link->player)
{
return false;
}
if (P_CheckSight (this, link))
{
return true;
}
}
return false;
}
void AMinotaur::Die (AActor *source, AActor *inflictor)
{
Super::Die (source, inflictor);
if (tracer && tracer->health > 0 && tracer->player)
{
// Search thinker list for minotaur
TThinkerIterator<AMinotaur> iterator;
AMinotaur *mo;
while ((mo = iterator.Next()) != NULL)
{
if (mo->health <= 0) continue;
// [RH] Minotaurs can't be morphed, so this isn't needed
//if (!(mo->flags&MF_COUNTKILL)) continue; // for morphed minotaurs
if (mo->flags&MF_CORPSE) continue;
if (mo->StartTime >= 0 && (level.maptime - StartTime) >= MAULATORTICS) continue;
if (mo->tracer != NULL && mo->tracer->player == tracer->player) break;
}
if (mo == NULL)
{
AInventory *power = tracer->FindInventory (RUNTIME_CLASS(APowerMinotaur));
if (power != NULL)
{
power->Destroy ();
}
}
}
}
bool AMinotaur::OkayToSwitchTarget (AActor *other)
{ // Minotaurs with masters never change their target until
// they've killed their current one.
if (tracer != NULL && tracer->health > 0)
return false;
if (other == tracer)
return false; // Do not target the master
return Super::OkayToSwitchTarget (other);
}
// Minotaur Friend ----------------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AMinotaurFriend, Hexen, -1, 0)
@ -323,6 +223,99 @@ AT_GAME_SET (Minotaur)
}
}
void AMinotaurFriend::BeginPlay ()
{
Super::BeginPlay ();
StartTime = -1;
}
void AMinotaurFriend::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << StartTime;
}
bool AMinotaurFriend::IsOkayToAttack (AActor *link)
{
if ((link->flags3&MF3_ISMONSTER) && (link != tracer))
{
if (!((link->flags ^ flags) & MF_FRIENDLY))
{ // Don't attack friends
if (link->flags & MF_FRIENDLY)
{
if (!deathmatch || link->FriendPlayer == 0 || FriendPlayer == 0 ||
link->FriendPlayer != FriendPlayer)
{
return false;
}
}
else
{
return false;
}
}
if (!(link->flags&MF_SHOOTABLE))
{
return false;
}
if (link->flags2&MF2_DORMANT)
{
return false;
}
if ((link->IsKindOf (RUNTIME_CLASS(AMinotaur))) &&
(link->tracer == tracer))
{
return false;
}
if (multiplayer && !deathmatch && link->player)
{
return false;
}
if (P_CheckSight (this, link))
{
return true;
}
}
return false;
}
void AMinotaurFriend::Die (AActor *source, AActor *inflictor)
{
Super::Die (source, inflictor);
if (tracer && tracer->health > 0 && tracer->player)
{
// Search thinker list for minotaur
TThinkerIterator<AMinotaurFriend> iterator;
AMinotaurFriend *mo;
while ((mo = iterator.Next()) != NULL)
{
if (mo->health <= 0) continue;
// [RH] Minotaurs can't be morphed, so this isn't needed
//if (!(mo->flags&MF_COUNTKILL)) continue; // for morphed minotaurs
if (mo->flags&MF_CORPSE) continue;
if (mo->StartTime >= 0 && (level.maptime - StartTime) >= MAULATORTICS) continue;
if (mo->tracer != NULL && mo->tracer->player == tracer->player) break;
}
if (mo == NULL)
{
AInventory *power = tracer->FindInventory (RUNTIME_CLASS(APowerMinotaur));
if (power != NULL)
{
power->Destroy ();
}
}
}
}
bool AMinotaurFriend::OkayToSwitchTarget (AActor *other)
{
if (other == tracer) return false; // Do not target the master
return Super::OkayToSwitchTarget (other);
}
void AMinotaurFriend::NoBlockingSet ()
{
// Do not drop anything
@ -358,6 +351,7 @@ IMPLEMENT_ACTOR (AMinotaurFX1, Raven, -1, 0)
PROP_DamageType (MOD_FIRE)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_NOTELEPORT)
PROP_Flags4 (MF4_NOTARGETSWITCH)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_MNTRFX1)
@ -531,7 +525,7 @@ void A_MinotaurAtk1 (AActor *actor)
void A_MinotaurDecide (AActor *actor)
{
bool friendly = !!(actor->flags & MF_FRIENDLY);
bool friendly = actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend));
angle_t angle;
AActor *target;
int dist;
@ -630,6 +624,7 @@ void A_MinotaurAtk2 (AActor *actor)
angle_t angle;
fixed_t momz;
fixed_t z;
bool friendly = actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend));
if (!actor->target)
{
@ -639,7 +634,7 @@ void A_MinotaurAtk2 (AActor *actor)
if (actor->CheckMeleeRange())
{
int damage;
damage = pr_atk.HitDice ((actor->flags & MF_FRIENDLY) ? 3 : 5);
damage = pr_atk.HitDice (friendly ? 3 : 5);
P_DamageMobj (actor->target, actor, actor, damage, MOD_HIT);
P_TraceBleed (damage, actor->target, actor);
return;
@ -670,6 +665,7 @@ void A_MinotaurAtk3 (AActor *actor)
{
AActor *mo;
player_t *player;
bool friendly = actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend));
if (!actor->target)
{
@ -680,7 +676,7 @@ void A_MinotaurAtk3 (AActor *actor)
{
int damage;
damage = pr_minotauratk3.HitDice ((actor->flags & MF_FRIENDLY) ? 3 : 5);
damage = pr_minotauratk3.HitDice (friendly ? 3 : 5);
P_DamageMobj (actor->target, actor, actor, damage, MOD_HIT);
P_TraceBleed (damage, actor->target, actor);
if ((player = actor->target->player) != NULL &&
@ -787,7 +783,7 @@ void A_MinotaurFade2 (AActor *actor)
void A_MinotaurRoam (AActor *actor)
{
AMinotaur *self = static_cast<AMinotaur *> (actor);
AMinotaurFriend *self = static_cast<AMinotaurFriend *> (actor);
// In case pain caused him to skip his fade in.
actor->RenderStyle = STYLE_Normal;
@ -829,14 +825,14 @@ void A_MinotaurRoam (AActor *actor)
void A_MinotaurLook (AActor *actor)
{
AMinotaur *self = static_cast<AMinotaur *> (actor);
if (!(self->flags & MF_FRIENDLY))
if (!actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend)))
{
A_Look (actor);
return;
}
AMinotaurFriend *self = static_cast<AMinotaurFriend *> (actor);
AActor *mo = NULL;
player_t *player;
fixed_t dist;
@ -900,7 +896,13 @@ void A_MinotaurLook (AActor *actor)
void A_MinotaurChase (AActor *actor)
{
AMinotaur *self = static_cast<AMinotaur *> (actor);
if (!actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend)))
{
A_Chase (actor);
return;
}
AMinotaurFriend *self = static_cast<AMinotaurFriend *> (actor);
// In case pain caused him to skip his fade in.
actor->RenderStyle = STYLE_Normal;
@ -911,12 +913,6 @@ void A_MinotaurChase (AActor *actor)
return;
}
if (!(self->flags & MF_FRIENDLY))
{
A_Chase (actor);
return;
}
if (pr_minotaurchase() < 30)
A_MinotaurLook (actor); // adjust to closest target
@ -952,6 +948,7 @@ void A_MinotaurChase (AActor *actor)
if (!P_Move (actor))
{
P_NewChaseDir (actor);
FaceMovementDirection (actor);
}
// Active sound

View file

@ -16,14 +16,8 @@ class AMinotaur : public AActor
public:
void NoBlockingSet ();
int DoSpecialDamage (AActor *target, int damage);
void BeginPlay ();
void Serialize (FArchive &arc);
public:
int StartTime;
bool IsOkayToAttack (AActor *target);
void Die (AActor *source, AActor *inflictor);
bool OkayToSwitchTarget (AActor *other);
bool Slam (AActor *);
void Tick ();
};
@ -32,7 +26,14 @@ class AMinotaurFriend : public AMinotaur
{
DECLARE_STATELESS_ACTOR (AMinotaurFriend, AMinotaur)
public:
int StartTime;
void NoBlockingSet ();
bool IsOkayToAttack (AActor *target);
void Die (AActor *source, AActor *inflictor);
bool OkayToSwitchTarget (AActor *other);
void BeginPlay ();
void Serialize (FArchive &arc);
};
#endif //__RAVENSHARED_H__

View file

@ -321,6 +321,22 @@ void APowerInvulnerable::EndEffect ()
}
}
//===========================================================================
//
// APowerInvuInvulnerable :: AlterWeaponSprite
//
//===========================================================================
void APowerInvulnerable::AlterWeaponSprite (vissprite_t *vis)
{
if (Owner->player->mo != NULL)
{
fixed_t wp_alpha;
Owner->player->mo->SpecialInvulnerabilityHandling (APlayerPawn::INVUL_GetAlpha, &wp_alpha);
if (wp_alpha != FIXED_MAX) vis->alpha = wp_alpha;
}
}
// Strength (aka Berserk) Powerup --------------------------------------------
IMPLEMENT_STATELESS_ACTOR (APowerStrength, Any, -1, 0)

View file

@ -59,6 +59,7 @@ protected:
void InitEffect ();
void DoEffect ();
void EndEffect ();
void AlterWeaponSprite (vissprite_t *vis);
};
class APowerStrength : public APowerup

View file

@ -152,8 +152,8 @@ int FRandom::Random2 ()
int FRandom::Random2 (int mask)
{
int t = (*this)(mask);
int u = (*this)(mask);
int t = (*this)() & mask;
int u = (*this)() & mask;
return t - u;
}

View file

@ -420,7 +420,7 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i
}
}
void P_DrawRailTrail (vec3_t start, vec3_t end)
void P_DrawRailTrail (AActor * source, vec3_t start, vec3_t end, int color1, int color2, float maxdiff, bool silent)
{
float length;
int steps, i;
@ -433,33 +433,44 @@ void P_DrawRailTrail (vec3_t start, vec3_t end)
if (length)
{
// 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;
vec3_t point;
float r;
float dirz;
length = 1 / length;
if (abs(mo->x - FLOAT2FIXED(start[0])) < 20 * FRACUNIT
&& (mo->y - FLOAT2FIXED(start[1])) < 20 * FRACUNIT)
{ // This player (probably) fired the railgun
S_Sound (mo, CHAN_WEAPON, "weapons/railgf", 1, ATTN_NORM);
}
else
if (!silent)
{
// Only consider sound in 2D (for now, anyway)
r = ((start[1] - FIXED2FLOAT(mo->y)) * (-dir[1]) -
(start[0] - FIXED2FLOAT(mo->x)) * (dir[0])) * length * length;
int sound;
// Allow other sounds than 'weapons/railgf'!
if (!source->player) sound = source->AttackSound;
else if (source->player->ReadyWeapon) sound = source->player->ReadyWeapon->AttackSound;
else sound = NULL;
if (!sound) sound=S_FindSound("weapons/railgf");
dirz = dir[2];
dir[2] = 0;
VectorMA (start, r, dir, point);
dir[2] = dirz;
// 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;
vec3_t point;
float r;
float dirz;
S_Sound (FLOAT2FIXED(point[0]), FLOAT2FIXED(point[1]),
CHAN_WEAPON, "weapons/railgf", 1, ATTN_NORM);
if (abs(mo->x - FLOAT2FIXED(start[0])) < 20 * FRACUNIT
&& (mo->y - FLOAT2FIXED(start[1])) < 20 * FRACUNIT)
{ // This player (probably) fired the railgun
S_SoundID (mo, CHAN_WEAPON, sound, 1, ATTN_NORM);
}
else
{
// Only consider sound in 2D (for now, anyway)
r = ((start[1] - FIXED2FLOAT(mo->y)) * (-dir[1]) -
(start[0] - FIXED2FLOAT(mo->x)) * (dir[0])) * length * length;
dirz = dir[2];
dir[2] = 0;
VectorMA (start, r, dir, point);
dir[2] = dirz;
S_SoundID (FLOAT2FIXED(point[0]), FLOAT2FIXED(point[1]), mo->z,
CHAN_WEAPON, sound, 1, ATTN_NORM);
}
}
}
else
@ -473,73 +484,113 @@ void P_DrawRailTrail (vec3_t start, vec3_t end)
VectorScale2 (extend, 3);
VectorScale (dir, 3, step);
VectorCopy (start, pos);
deg = 270;
for (i = steps; i; i--)
if (color1 != -1)
{
particle_t *p = NewParticle ();
vec3_t tempvec;
if (!p)
return;
p->trans = 255;
p->ttl = 35;
p->fade = FADEFROMTTL(35);
p->size = 3;
RotatePointAroundVector (tempvec, dir, extend, deg);
p->velx = FLOAT2FIXED(tempvec[0])>>4;
p->vely = FLOAT2FIXED(tempvec[1])>>4;
p->velz = FLOAT2FIXED(tempvec[2])>>4;
VectorAdd (tempvec, pos, tempvec);
deg += 14;
if (deg >= 360)
deg -= 360;
p->x = FLOAT2FIXED(tempvec[0]);
p->y = FLOAT2FIXED(tempvec[1]);
p->z = FLOAT2FIXED(tempvec[2]);
VectorAdd (pos, step, pos);
color1 = color1==0? -1: ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1));
VectorCopy (start, pos);
deg = 270;
for (i = steps; i; i--)
{
int rand = M_Random();
particle_t *p = NewParticle ();
vec3_t tempvec;
if (rand < 155)
p->color = rblue2;
else if (rand < 188)
p->color = rblue1;
else if (rand < 222)
p->color = rblue3;
else
p->color = rblue4;
if (!p)
return;
p->trans = 255;
p->ttl = 35;
p->fade = FADEFROMTTL(35);
p->size = 3;
RotatePointAroundVector (tempvec, dir, extend, deg);
p->velx = FLOAT2FIXED(tempvec[0])>>4;
p->vely = FLOAT2FIXED(tempvec[1])>>4;
p->velz = FLOAT2FIXED(tempvec[2])>>4;
VectorAdd (tempvec, pos, tempvec);
deg += 14;
if (deg >= 360)
deg -= 360;
p->x = FLOAT2FIXED(tempvec[0]);
p->y = FLOAT2FIXED(tempvec[1]);
p->z = FLOAT2FIXED(tempvec[2]);
VectorAdd (pos, step, pos);
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;
}
}
}
VectorCopy (start, pos);
for (i = steps; i; i--)
if (color2 != -1)
{
particle_t *p = JitterParticle (33);
color2 = color2==0? -1: ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2));
vec3_t diff;
VectorSet (diff, 0, 0, 0);
if (!p)
return;
p->size = 2;
p->x = FLOAT2FIXED(pos[0]);
p->y = FLOAT2FIXED(pos[1]);
p->z = FLOAT2FIXED(pos[2]);
p->accz -= FRACUNIT/4096;
VectorAdd (pos, step, pos);
VectorCopy (start, pos);
for (i = steps; i; i--)
{
int rand = M_Random();
particle_t *p = JitterParticle (33);
if (rand < 85)
p->color = grey4;
else if (rand < 170)
p->color = grey2;
else
p->color = grey1;
if (!p)
return;
if (maxdiff > 0)
{
int rnd = M_Random ();
if (rnd & 1)
diff[0] = clamp<float> (diff[0] + ((rnd & 8) ? 1 : -1), -maxdiff, maxdiff);
if (rnd & 2)
diff[1] = clamp<float> (diff[1] + ((rnd & 16) ? 1 : -1), -maxdiff, maxdiff);
if (rnd & 4)
diff[2] = clamp<float> (diff[2] + ((rnd & 32) ? 1 : -1), -maxdiff, maxdiff);
}
vec3_t postmp;
VectorCopy (pos, postmp);
VectorAdd (postmp, diff, postmp);
p->size = 2;
p->x = FLOAT2FIXED(postmp[0]);
p->y = FLOAT2FIXED(postmp[1]);
p->z = FLOAT2FIXED(postmp[2]);
if (color1 != -1)
p->accz -= FRACUNIT/4096;
VectorAdd (pos, step, pos);
if (color2==-1)
{
{
int rand = M_Random();
if (rand < 85)
p->color = grey4;
else if (rand < 170)
p->color = grey2;
else
p->color = grey1;
}
p->color = white;
}
else
{
p->color = color2;
}
}
p->color = white;
}
}

View file

@ -58,7 +58,7 @@ void P_RunEffects (void);
void P_RunEffect (AActor *actor, int effects);
void P_DrawRailTrail (vec3_t start, vec3_t end);
void P_DrawRailTrail (AActor * source, vec3_t start, vec3_t end, int color1, int color2, float maxdiff = 0, bool silent = false);
void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int kind);
void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind);
void P_DisconnectEffect (AActor *actor);

View file

@ -303,7 +303,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target,
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
void P_TraceBleed (int damage, AActor *target); // random direction version
void P_RailAttack (AActor *source, int damage, int offset); // [RH] Shoot a railgun
void P_RailAttack (AActor *source, int damage, int offset, int color1 = 0, int color2 = 0, float maxdiff = 0, bool silent = false); // [RH] Shoot a railgun
bool P_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec);
bool P_CheckMissileSpawn (AActor *missile);

View file

@ -2961,7 +2961,7 @@ static bool ProcessRailHit (FTraceResults &res)
return true;
}
void P_RailAttack (AActor *source, int damage, int offset)
void P_RailAttack (AActor *source, int damage, int offset, int color1, int color2, float maxdiff, bool silent)
{
fixed_t vx, vy, vz;
angle_t angle, pitch;
@ -3064,7 +3064,7 @@ void P_RailAttack (AActor *source, int damage, int offset)
}
VectorFixedSet (end, trace.X, trace.Y, trace.Z);
P_DrawRailTrail (start, end);
P_DrawRailTrail (source, start, end, color1, color2, maxdiff, silent);
}
//

View file

@ -449,8 +449,9 @@ bool APlayerPawn::DoHealingRadius (APlayerPawn *other)
return false;
}
void APlayerPawn::SpecialInvulnerabilityHandling (EInvulState setting)
void APlayerPawn::SpecialInvulnerabilityHandling (EInvulState setting, fixed_t * pAlpha)
{
if (setting == INVUL_GetAlpha && pAlpha!=NULL) *pAlpha=FIXED_MAX; // indicates no change
}
/*

View file

@ -1668,8 +1668,8 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
else
{
int c = V_GetColor (NULL, sc_String);
// 0 needs to be the default so we have to add 1 here!
v = 1 + ColorMatcher.Pick (RPART (c), GPART (c), BPART (c));
// 0 needs to be the default so we have to mark the color.
v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
}
break;

View file

@ -874,14 +874,7 @@ void A_RailAttack (AActor * self)
if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return; // out of ammo
}
// Need to keep the default colors
if (Color1==0) Color1 = ColorMatcher.Pick (0, 0, 255);
else if (Color1>0) Color1--;
if (Color2==0) Color2 = ColorMatcher.Pick (255, 255, 255);
else if (Color2>0) Color2--;
P_RailAttack (self, Damage, Spawnofs_XY/*, Color1, Color2, MaxDiff, Silent*/);
P_RailAttack (self, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent);
}
//==========================================================================
@ -938,14 +931,7 @@ void A_CustomRailgun (AActor *actor)
}
}
// Need to keep the default colors
if (Color1==0) Color1 = ColorMatcher.Pick (0, 0, 255);
else if (Color1>0) Color1--;
if (Color2==0) Color2 = ColorMatcher.Pick (255, 255, 255);
else if (Color2>0) Color2--;
P_RailAttack (actor, Damage, Spawnofs_XY/*, Color1, Color2, MaxDiff, Silent*/);
P_RailAttack (actor, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent);
}
//===========================================================================