diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 0a17fab9e..c229c8f27 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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 diff --git a/src/c_console.cpp b/src/c_console.cpp index a86dd502a..21f7e1740 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -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; } diff --git a/src/d_player.h b/src/d_player.h index 21a52c50e..07e2fe234 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -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); diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index d4d2dbd31..a907ee510 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -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) diff --git a/src/g_hexen/a_clericplayer.cpp b/src/g_hexen/a_clericplayer.cpp index 0cfd4389d..dd9c4fd9f 100644 --- a/src/g_hexen/a_clericplayer.cpp +++ b/src/g_hexen/a_clericplayer.cpp @@ -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(FRACUNIT/4 + alpha*3/4, FRACUNIT); + } } // Cleric Weapon Base Class ------------------------------------------------- diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h index 1890e50dc..e099e235e 100644 --- a/src/g_hexen/a_hexenglobal.h +++ b/src/g_hexen/a_hexenglobal.h @@ -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 diff --git a/src/g_hexen/a_mageplayer.cpp b/src/g_hexen/a_mageplayer.cpp index c1626ebff..0356a48f6 100644 --- a/src/g_hexen/a_mageplayer.cpp +++ b/src/g_hexen/a_mageplayer.cpp @@ -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 --------------------------------------------------- diff --git a/src/g_hexen/a_summon.cpp b/src/g_hexen/a_summon.cpp index 2837c45c0..d310b4f46 100644 --- a/src/g_hexen/a_summon.cpp +++ b/src/g_hexen/a_summon.cpp @@ -132,7 +132,7 @@ bool AArtiDarkServant::Use (bool pickup) void A_Summon (AActor *actor) { - AMinotaur *mo; + AMinotaurFriend *mo; mo = Spawn (actor->x, actor->y, actor->z); if (mo) diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 3488e2f27..68e735890 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -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 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 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 (actor); + AMinotaurFriend *self = static_cast (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 (actor); - if (!(self->flags & MF_FRIENDLY)) + if (!actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend))) { A_Look (actor); return; } + AMinotaurFriend *self = static_cast (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 (actor); + if (!actor->IsKindOf(RUNTIME_CLASS(AMinotaurFriend))) + { + A_Chase (actor); + return; + } + + AMinotaurFriend *self = static_cast (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 diff --git a/src/g_raven/ravenshared.h b/src/g_raven/ravenshared.h index ab5ebe3a2..8aa35dd5f 100644 --- a/src/g_raven/ravenshared.h +++ b/src/g_raven/ravenshared.h @@ -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__ diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 71db0b0a8..2bf099d5b 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -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) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 43ecc72ac..cb2bb044d 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -59,6 +59,7 @@ protected: void InitEffect (); void DoEffect (); void EndEffect (); + void AlterWeaponSprite (vissprite_t *vis); }; class APowerStrength : public APowerup diff --git a/src/m_random.cpp b/src/m_random.cpp index 4e8899c07..c6b5e36a7 100644 --- a/src/m_random.cpp +++ b/src/m_random.cpp @@ -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; } diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 81f2225da..15e8d493e 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -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 (diff[0] + ((rnd & 8) ? 1 : -1), -maxdiff, maxdiff); + if (rnd & 2) + diff[1] = clamp (diff[1] + ((rnd & 16) ? 1 : -1), -maxdiff, maxdiff); + if (rnd & 4) + diff[2] = clamp (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; } } diff --git a/src/p_effect.h b/src/p_effect.h index c67613121..463b051c6 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -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); diff --git a/src/p_local.h b/src/p_local.h index e9f0d263d..f6c5b04e2 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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); diff --git a/src/p_map.cpp b/src/p_map.cpp index f7bdd9ab2..2a0f80a08 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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); } // diff --git a/src/p_user.cpp b/src/p_user.cpp index 7fe7b761e..59d6287f1 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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 } /* diff --git a/src/thingdef.cpp b/src/thingdef.cpp index be1c4001c..1f1dd504c 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -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; diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp index d201db2b8..1c4fd0c04 100644 --- a/src/thingdef_codeptr.cpp +++ b/src/thingdef_codeptr.cpp @@ -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); } //===========================================================================