mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- scriptified APowerInvisibility.
- changed AlterWeaponSprite so that it doesn't expose renderer internals to the script code.
This commit is contained in:
parent
a5edd421bd
commit
d3ab691afb
12 changed files with 339 additions and 349 deletions
|
@ -46,7 +46,7 @@
|
|||
struct subsector_t;
|
||||
struct FBlockNode;
|
||||
struct FPortalGroupArray;
|
||||
|
||||
struct visstyle_t;
|
||||
//
|
||||
// NOTES: AActor
|
||||
//
|
||||
|
@ -617,6 +617,7 @@ public:
|
|||
// Returns true if the missile should be allowed to explode anyway
|
||||
bool AdjustReflectionAngle (AActor *thing, DAngle &angle);
|
||||
int AbsorbDamage(int damage, FName dmgtype);
|
||||
void AlterWeaponSprite(visstyle_t *vis);
|
||||
|
||||
// Returns true if this actor is within melee range of its target
|
||||
bool CheckMeleeRange();
|
||||
|
|
|
@ -540,25 +540,6 @@ void APowerInvulnerable::EndEffect ()
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvulnerable :: AlterWeaponSprite
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int APowerInvulnerable::AlterWeaponSprite (visstyle_t *vis)
|
||||
{
|
||||
int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis);
|
||||
if (Owner != NULL)
|
||||
{
|
||||
if (Mode == NAME_Ghost && !(Owner->flags & MF_SHADOW))
|
||||
{
|
||||
vis->Alpha = MIN<float>(0.25f + (float)Owner->Alpha*0.75f, 1.f);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
// Strength (aka Berserk) Powerup --------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(APowerStrength, false, false)
|
||||
|
@ -624,211 +605,6 @@ PalEntry APowerStrength::GetBlend ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Invisibility Powerup ------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(APowerInvisibility, false, false)
|
||||
|
||||
// Invisibility flag combos
|
||||
#define INVISIBILITY_FLAGS1 (MF_SHADOW)
|
||||
#define INVISIBILITY_FLAGS3 (MF3_GHOST)
|
||||
#define INVISIBILITY_FLAGS5 (MF5_CANTSEEK)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerInvisibility::InitEffect ()
|
||||
{
|
||||
Super::InitEffect();
|
||||
// This used to call CommonInit(), which used to contain all the code that's repeated every
|
||||
// tic, plus the following code that needs to happen once and only once.
|
||||
// The CommonInit() code has been moved to DoEffect(), so this now ends with a call to DoEffect(),
|
||||
// and DoEffect() no longer needs to call InitEffect(). CommonInit() has been removed for being redundant.
|
||||
if (Owner != NULL)
|
||||
{
|
||||
flags &= ~(Owner->flags & INVISIBILITY_FLAGS1);
|
||||
Owner->flags |= flags & INVISIBILITY_FLAGS1;
|
||||
flags3 &= ~(Owner->flags3 & INVISIBILITY_FLAGS3);
|
||||
Owner->flags3 |= flags3 & INVISIBILITY_FLAGS3;
|
||||
flags5 &= ~(Owner->flags5 & INVISIBILITY_FLAGS5);
|
||||
Owner->flags5 |= flags5 & INVISIBILITY_FLAGS5;
|
||||
|
||||
CallDoEffect();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: DoEffect
|
||||
//
|
||||
//===========================================================================
|
||||
void APowerInvisibility::DoEffect ()
|
||||
{
|
||||
Super::DoEffect();
|
||||
// Due to potential interference with other PowerInvisibility items
|
||||
// the effect has to be refreshed each tic.
|
||||
double ts = (Strength / 100) * (special1 + 1);
|
||||
|
||||
if (ts > 1.) ts = 1.;
|
||||
Owner->Alpha = clamp((1. - ts), 0., 1.);
|
||||
switch (Mode)
|
||||
{
|
||||
case (NAME_Fuzzy):
|
||||
Owner->RenderStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case (NAME_Opaque):
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
case (NAME_Additive):
|
||||
Owner->RenderStyle = STYLE_Add;
|
||||
break;
|
||||
case (NAME_Stencil):
|
||||
Owner->RenderStyle = STYLE_Stencil;
|
||||
break;
|
||||
case (NAME_AddStencil) :
|
||||
Owner->RenderStyle = STYLE_AddStencil;
|
||||
break;
|
||||
case (NAME_TranslucentStencil) :
|
||||
Owner->RenderStyle = STYLE_TranslucentStencil;
|
||||
break;
|
||||
case (NAME_None) :
|
||||
case (NAME_Cumulative):
|
||||
case (NAME_Translucent):
|
||||
Owner->RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
default: // Something's wrong
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->Alpha = 1.;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerInvisibility::EndEffect ()
|
||||
{
|
||||
Super::EndEffect();
|
||||
if (Owner != NULL)
|
||||
{
|
||||
Owner->flags &= ~(flags & INVISIBILITY_FLAGS1);
|
||||
Owner->flags3 &= ~(flags3 & INVISIBILITY_FLAGS3);
|
||||
Owner->flags5 &= ~(flags5 & INVISIBILITY_FLAGS5);
|
||||
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->Alpha = 1.;
|
||||
|
||||
// Check whether there are other invisibility items and refresh their effect.
|
||||
// If this isn't done there will be one incorrectly drawn frame when this
|
||||
// item expires.
|
||||
AInventory *item = Owner->Inventory;
|
||||
while (item != NULL)
|
||||
{
|
||||
if (item->IsKindOf(RUNTIME_CLASS(APowerInvisibility)) && item != this)
|
||||
{
|
||||
static_cast<APowerInvisibility*>(item)->DoEffect();
|
||||
}
|
||||
item = item->Inventory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: AlterWeaponSprite
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis)
|
||||
{
|
||||
int changed = Inventory == NULL ? false : Inventory->AlterWeaponSprite(vis);
|
||||
// Blink if the powerup is wearing off
|
||||
if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8))
|
||||
{
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
vis->Alpha = 1.f;
|
||||
return 1;
|
||||
}
|
||||
else if (changed == 1)
|
||||
{
|
||||
// something else set the weapon sprite back to opaque but this item is still active.
|
||||
float ts = float((Strength / 100) * (special1 + 1));
|
||||
vis->Alpha = clamp<>((1.f - ts), 0.f, 1.f);
|
||||
switch (Mode)
|
||||
{
|
||||
case (NAME_Fuzzy):
|
||||
vis->RenderStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case (NAME_Opaque):
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
case (NAME_Additive):
|
||||
vis->RenderStyle = STYLE_Add;
|
||||
break;
|
||||
case (NAME_Stencil):
|
||||
vis->RenderStyle = STYLE_Stencil;
|
||||
break;
|
||||
case (NAME_TranslucentStencil) :
|
||||
vis->RenderStyle = STYLE_TranslucentStencil;
|
||||
break;
|
||||
case (NAME_AddStencil) :
|
||||
vis->RenderStyle = STYLE_AddStencil;
|
||||
break;
|
||||
case (NAME_None) :
|
||||
case (NAME_Cumulative):
|
||||
case (NAME_Translucent):
|
||||
default:
|
||||
vis->RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible
|
||||
if ((vis->Alpha < 0.25f && special1 > 0) || (vis->Alpha == 0))
|
||||
{
|
||||
vis->Alpha = clamp((1.f - float(Strength/100)), 0.f, 1.f);
|
||||
vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap;
|
||||
}
|
||||
return -1; // This item is valid so another one shouldn't reset the translucency
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: HandlePickup
|
||||
//
|
||||
// If the player already has the first stage of a cumulative powerup, getting
|
||||
// it again increases the player's alpha. (But shouldn't this be in Use()?)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool APowerInvisibility::HandlePickup (AInventory *item)
|
||||
{
|
||||
if (Mode == NAME_Cumulative && ((Strength * special1) < 1.) && item->GetClass() == GetClass())
|
||||
{
|
||||
APowerup *power = static_cast<APowerup *>(item);
|
||||
if (power->EffectTics == 0)
|
||||
{
|
||||
power->ItemFlags |= IF_PICKUPGOOD;
|
||||
return true;
|
||||
}
|
||||
// Only increase the EffectTics, not decrease it.
|
||||
// Color also gets transferred only when the new item has an effect.
|
||||
if (power->EffectTics > EffectTics)
|
||||
{
|
||||
EffectTics = power->EffectTics;
|
||||
BlendColor = power->BlendColor;
|
||||
}
|
||||
special1++; // increases power
|
||||
power->ItemFlags |= IF_PICKUPGOOD;
|
||||
return true;
|
||||
}
|
||||
return Super::HandlePickup (item);
|
||||
}
|
||||
|
||||
// Speed Powerup -------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(APowerSpeed, false, false)
|
||||
|
|
|
@ -64,7 +64,6 @@ protected:
|
|||
virtual void InitEffect () override;
|
||||
virtual void DoEffect () override;
|
||||
virtual void EndEffect () override;
|
||||
virtual int AlterWeaponSprite (visstyle_t *vis) override;
|
||||
};
|
||||
|
||||
class APowerStrength : public APowerup
|
||||
|
@ -78,17 +77,6 @@ protected:
|
|||
virtual bool HandlePickup (AInventory *item) override;
|
||||
};
|
||||
|
||||
class APowerInvisibility : public APowerup
|
||||
{
|
||||
DECLARE_CLASS (APowerInvisibility, APowerup)
|
||||
protected:
|
||||
virtual bool HandlePickup (AInventory *item) override;
|
||||
virtual void InitEffect () override;
|
||||
virtual void DoEffect () override;
|
||||
virtual void EndEffect () override;
|
||||
virtual int AlterWeaponSprite (visstyle_t *vis) override;
|
||||
};
|
||||
|
||||
class APowerSpeed : public APowerup
|
||||
{
|
||||
DECLARE_CLASS (APowerSpeed, APowerup)
|
||||
|
|
|
@ -783,24 +783,6 @@ bool AInventory::GetNoTeleportFreeze ()
|
|||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: AlterWeaponSprite
|
||||
//
|
||||
// Allows inventory items to alter a player's weapon sprite just before it
|
||||
// is drawn.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int AInventory::AlterWeaponSprite (visstyle_t *vis)
|
||||
{
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
return Inventory->AlterWeaponSprite (vis);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: Use
|
||||
|
|
|
@ -133,7 +133,6 @@ public:
|
|||
|
||||
// visual stuff is for later. Right now the VM has not yet access to the needed functionality.
|
||||
virtual bool DrawPowerup(int x, int y);
|
||||
virtual int AlterWeaponSprite(visstyle_t *vis);
|
||||
|
||||
|
||||
// virtual on the script side only.
|
||||
|
|
|
@ -310,21 +310,21 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
visstyle_t vis;
|
||||
|
||||
vis.RenderStyle=playermo->RenderStyle;
|
||||
vis.Alpha=playermo->Alpha;
|
||||
vis.colormap = NULL;
|
||||
if (playermo->Inventory)
|
||||
vis.RenderStyle = STYLE_Count;
|
||||
vis.Alpha = playermo->Alpha;
|
||||
vis.Invert = false;
|
||||
playermo->AlterWeaponSprite(&vis);
|
||||
|
||||
FRenderStyle RenderStyle;
|
||||
if (vis.RenderStyle == STYLE_Count) RenderStyle = playermo->RenderStyle;
|
||||
else RenderStyle = vis.RenderStyle;
|
||||
|
||||
if (vis.Invert)
|
||||
{
|
||||
playermo->Inventory->AlterWeaponSprite(&vis);
|
||||
if (vis.colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap &&
|
||||
gl_fixedcolormap == CM_DEFAULT)
|
||||
{
|
||||
// this only happens for Strife's inverted weapon sprite
|
||||
vis.RenderStyle.Flags |= STYLEF_InvertSource;
|
||||
}
|
||||
// this only happens for Strife's inverted weapon sprite
|
||||
RenderStyle.Flags |= STYLEF_InvertSource;
|
||||
}
|
||||
if (vis.RenderStyle.AsDWORD == 0)
|
||||
if (RenderStyle.AsDWORD == 0)
|
||||
{
|
||||
// This is RenderStyle None.
|
||||
return;
|
||||
|
@ -334,32 +334,32 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
int OverrideShader = -1;
|
||||
float trans = 0.f;
|
||||
if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
|
||||
if (RenderStyle.BlendOp >= STYLEOP_Fuzz && RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
|
||||
{
|
||||
vis.RenderStyle.CheckFuzz();
|
||||
if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz)
|
||||
RenderStyle.CheckFuzz();
|
||||
if (RenderStyle.BlendOp == STYLEOP_Fuzz)
|
||||
{
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
// Todo: implement shader selection here
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
OverrideShader = gl_fuzztype + 4;
|
||||
trans = 0.99f; // trans may not be 1 here
|
||||
}
|
||||
else
|
||||
{
|
||||
vis.RenderStyle.BlendOp = STYLEOP_Shadow;
|
||||
RenderStyle.BlendOp = STYLEOP_Shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl_SetRenderStyle(vis.RenderStyle, false, false);
|
||||
gl_SetRenderStyle(RenderStyle, false, false);
|
||||
|
||||
if (vis.RenderStyle.Flags & STYLEF_TransSoulsAlpha)
|
||||
if (RenderStyle.Flags & STYLEF_TransSoulsAlpha)
|
||||
{
|
||||
trans = transsouls;
|
||||
}
|
||||
else if (vis.RenderStyle.Flags & STYLEF_Alpha1)
|
||||
else if (RenderStyle.Flags & STYLEF_Alpha1)
|
||||
{
|
||||
trans = 1.f;
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
ll = 255;
|
||||
}
|
||||
// set the lighting parameters
|
||||
if (vis.RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
if (RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
{
|
||||
gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, cmc.desaturation);
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
}
|
||||
|
||||
|
||||
DrawPSprite(player, psp, sx, sy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
DrawPSprite(player, psp, sx, sy, hudModelStep, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
|
|
|
@ -3629,6 +3629,25 @@ int AActor::AbsorbDamage(int damage, FName dmgtype)
|
|||
return damage;
|
||||
}
|
||||
|
||||
void AActor::AlterWeaponSprite(visstyle_t *vis)
|
||||
{
|
||||
int changed = 0;
|
||||
TArray<AInventory *> items;
|
||||
// This needs to go backwards through the items but the list has no backlinks.
|
||||
for (AInventory *item = Inventory; item != nullptr; item = item->Inventory)
|
||||
{
|
||||
items.Push(item);
|
||||
}
|
||||
for(int i=items.Size()-1;i>=0;i--)
|
||||
{
|
||||
IFVIRTUALPTR(items[i], AInventory, AlterWeaponSprite)
|
||||
{
|
||||
VMValue params[3] = { items[i], vis, &changed };
|
||||
GlobalVMStack.Call(func, params, 3, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AActor::PlayActiveSound ()
|
||||
{
|
||||
if (ActiveSound && !S_IsActorPlayingSomething (this, CHAN_VOICE, -1))
|
||||
|
|
|
@ -1489,9 +1489,9 @@ typedef BYTE lighttable_t; // This could be wider for >8 bit display.
|
|||
// This encapsulates the fields of vissprite_t that can be altered by AlterWeaponSprite
|
||||
struct visstyle_t
|
||||
{
|
||||
lighttable_t *colormap;
|
||||
bool Invert;
|
||||
float Alpha;
|
||||
FRenderStyle RenderStyle;
|
||||
ERenderStyle RenderStyle;
|
||||
};
|
||||
|
||||
|
||||
|
|
130
src/r_things.cpp
130
src/r_things.cpp
|
@ -406,11 +406,11 @@ void R_DrawVisSprite (vissprite_t *vis)
|
|||
}
|
||||
|
||||
fixed_t centeryfrac = FLOAT2FIXED(CenterY);
|
||||
R_SetColorMapLight(vis->Style.colormap, 0.0f, 0);
|
||||
R_SetColorMapLight(vis->colormap, 0.0f, 0);
|
||||
|
||||
mode = R_SetPatchStyle (vis->Style.RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor);
|
||||
mode = R_SetPatchStyle (vis->RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor);
|
||||
|
||||
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
|
||||
// it is the brightest one. We need to get back to the proper light level for
|
||||
// this sprite.
|
||||
|
@ -521,7 +521,7 @@ void R_DrawWallSprite(vissprite_t *spr)
|
|||
bool rereadcolormap = true;
|
||||
|
||||
// Decals that are added to the scene must fade to black.
|
||||
if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
|
||||
{
|
||||
usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
|
||||
rereadcolormap = false;
|
||||
|
@ -559,7 +559,7 @@ void R_DrawWallSprite(vissprite_t *spr)
|
|||
dc_x = x1;
|
||||
ESPSResult mode;
|
||||
|
||||
mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||
mode = R_SetPatchStyle (spr->RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||
|
||||
// R_SetPatchStyle can modify basecolormap.
|
||||
if (rereadcolormap)
|
||||
|
@ -646,8 +646,8 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
|
|||
int flags = 0;
|
||||
|
||||
// Do setup for blending.
|
||||
R_SetColorMapLight(spr->Style.colormap, 0.0f, 0);
|
||||
mode = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||
R_SetColorMapLight(spr->colormap, 0.0f, 0);
|
||||
mode = R_SetPatchStyle(spr->RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor);
|
||||
|
||||
if (mode == DontDraw)
|
||||
{
|
||||
|
@ -672,7 +672,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
|
|||
|
||||
// Render the voxel, either directly to the screen or offscreen.
|
||||
R_DrawVoxel(spr->pa.vpos, spr->pa.vang, spr->gpos, spr->Angle,
|
||||
spr->xscale, FLOAT2FIXED(spr->yscale), spr->voxel, spr->Style.colormap, cliptop, clipbot,
|
||||
spr->xscale, FLOAT2FIXED(spr->yscale), spr->voxel, spr->colormap, cliptop, clipbot,
|
||||
minslabz, maxslabz, flags);
|
||||
|
||||
// Blend the voxel, if that's what we need to do.
|
||||
|
@ -1051,7 +1051,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
vis->renderflags = renderflags;
|
||||
if(thing->flags5 & MF5_BRIGHT)
|
||||
vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
||||
vis->Style.RenderStyle = thing->RenderStyle;
|
||||
vis->RenderStyle = thing->RenderStyle;
|
||||
vis->FillColor = thing->fillcolor;
|
||||
vis->Translation = thing->Translation; // [RH] thing translation table
|
||||
vis->FakeFlatStat = fakeside;
|
||||
|
@ -1079,9 +1079,9 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
// The software renderer cannot invert the source without inverting the overlay
|
||||
// too. That means if the source is inverted, we need to do the reverse of what
|
||||
// the invert overlay flag says to do.
|
||||
INTBOOL invertcolormap = (vis->Style.RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
|
||||
if (vis->Style.RenderStyle.Flags & STYLEF_InvertSource)
|
||||
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
invertcolormap = !invertcolormap;
|
||||
}
|
||||
|
@ -1093,12 +1093,12 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
}
|
||||
|
||||
// Sprites that are added to the scene must fade to black.
|
||||
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
||||
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
||||
{
|
||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
||||
}
|
||||
|
||||
if (vis->Style.RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
if (invertcolormap)
|
||||
{ // Fade to white
|
||||
|
@ -1114,7 +1114,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
// get light level
|
||||
if (fixedcolormap != NULL)
|
||||
{ // fixed map
|
||||
vis->Style.colormap = fixedcolormap;
|
||||
vis->colormap = fixedcolormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1124,17 +1124,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
}
|
||||
if (fixedlightlev >= 0)
|
||||
{
|
||||
vis->Style.colormap = mybasecolormap->Maps + fixedlightlev;
|
||||
vis->colormap = mybasecolormap->Maps + fixedlightlev;
|
||||
}
|
||||
else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)))
|
||||
{ // full bright
|
||||
vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps;
|
||||
vis->colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps;
|
||||
}
|
||||
else
|
||||
{ // diminished light
|
||||
vis->ColormapNum = GETPALOOKUP(
|
||||
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
||||
vis->Style.colormap = mybasecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
vis->colormap = mybasecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1196,7 +1196,7 @@ static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID p
|
|||
vis->deltay = float(pos.Y - ViewPos.Y);
|
||||
vis->renderflags = renderflags;
|
||||
if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
||||
vis->Style.RenderStyle = thing->RenderStyle;
|
||||
vis->RenderStyle = thing->RenderStyle;
|
||||
vis->FillColor = thing->fillcolor;
|
||||
vis->Translation = thing->Translation;
|
||||
vis->FakeFlatStat = 0;
|
||||
|
@ -1210,7 +1210,7 @@ static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID p
|
|||
vis->bWallSprite = true;
|
||||
vis->ColormapNum = GETPALOOKUP(
|
||||
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
||||
vis->Style.colormap = basecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
vis->colormap = basecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
vis->wallc = wallc;
|
||||
}
|
||||
|
||||
|
@ -1414,21 +1414,21 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double
|
|||
if (pspr->GetID() < PSP_TARGETCENTER)
|
||||
{
|
||||
vis->Style.Alpha = float(owner->Alpha);
|
||||
vis->Style.RenderStyle = owner->RenderStyle;
|
||||
vis->RenderStyle = owner->RenderStyle;
|
||||
|
||||
// The software renderer cannot invert the source without inverting the overlay
|
||||
// too. That means if the source is inverted, we need to do the reverse of what
|
||||
// the invert overlay flag says to do.
|
||||
INTBOOL invertcolormap = (vis->Style.RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
|
||||
if (vis->Style.RenderStyle.Flags & STYLEF_InvertSource)
|
||||
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
invertcolormap = !invertcolormap;
|
||||
}
|
||||
|
||||
FDynamicColormap *mybasecolormap = basecolormap;
|
||||
|
||||
if (vis->Style.RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
if (invertcolormap)
|
||||
{ // Fade to white
|
||||
|
@ -1443,7 +1443,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double
|
|||
|
||||
if (realfixedcolormap != nullptr)
|
||||
{ // fixed color
|
||||
vis->Style.colormap = realfixedcolormap->Colormap;
|
||||
vis->colormap = realfixedcolormap->Colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1453,44 +1453,40 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double
|
|||
}
|
||||
if (fixedlightlev >= 0)
|
||||
{
|
||||
vis->Style.colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (mybasecolormap->Maps + fixedlightlev);
|
||||
vis->colormap = (r_fullbrightignoresectorcolor) ? (FullNormalLight.Maps + fixedlightlev) : (mybasecolormap->Maps + fixedlightlev);
|
||||
}
|
||||
else if (!foggy && pspr->GetState()->GetFullbright())
|
||||
{ // full bright
|
||||
vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps; // [RH] use basecolormap
|
||||
vis->colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps; // [RH] use basecolormap
|
||||
}
|
||||
else
|
||||
{ // local light
|
||||
vis->Style.colormap = mybasecolormap->Maps + (GETPALOOKUP(0, spriteshade) << COLORMAPSHIFT);
|
||||
vis->colormap = mybasecolormap->Maps + (GETPALOOKUP(0, spriteshade) << COLORMAPSHIFT);
|
||||
}
|
||||
}
|
||||
if (camera->Inventory != nullptr)
|
||||
{
|
||||
lighttable_t *oldcolormap = vis->Style.colormap;
|
||||
camera->Inventory->AlterWeaponSprite(&vis->Style);
|
||||
if (vis->Style.colormap != oldcolormap)
|
||||
vis->Style.RenderStyle = STYLE_Count;
|
||||
vis->Style.Invert = false;
|
||||
camera->AlterWeaponSprite(&vis->Style);
|
||||
if (vis->Style.Invert)
|
||||
{
|
||||
// The colormap has changed. Is it one we can easily identify?
|
||||
// If not, then don't bother trying to identify it for
|
||||
// hardware accelerated drawing.
|
||||
if (vis->Style.colormap < SpecialColormaps[0].Colormap ||
|
||||
vis->Style.colormap > SpecialColormaps.Last().Colormap)
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
vis->colormap = SpecialColormaps[0].Colormap;
|
||||
|
||||
// Has the basecolormap changed? If so, we can't hardware accelerate it,
|
||||
// since we don't know what it is anymore.
|
||||
else if (vis->Style.colormap < mybasecolormap->Maps ||
|
||||
vis->Style.colormap >= mybasecolormap->Maps + NUMCOLORMAPS * 256)
|
||||
if (vis->colormap < mybasecolormap->Maps ||
|
||||
vis->colormap >= mybasecolormap->Maps + NUMCOLORMAPS * 256)
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
}
|
||||
if (vis->Style.RenderStyle != STYLE_Count) vis->RenderStyle = vis->Style.RenderStyle;
|
||||
}
|
||||
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
||||
// not accelerate.
|
||||
if (!r_shadercolormaps && (vis->Style.colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis->Style.colormap <= SpecialColormaps.Last().Colormap))
|
||||
if (!r_shadercolormaps && (vis->colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis->colormap <= SpecialColormaps.Last().Colormap))
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
|
@ -1517,15 +1513,15 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double
|
|||
else
|
||||
{
|
||||
colormap_to_use = basecolormap;
|
||||
vis->Style.colormap = basecolormap->Maps;
|
||||
vis->Style.RenderStyle = STYLE_Normal;
|
||||
vis->colormap = basecolormap->Maps;
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
}
|
||||
|
||||
// Check for hardware-assisted 2D. If it's available, and this sprite is not
|
||||
// fuzzy, don't draw it until after the switch to 2D mode.
|
||||
if (!noaccel && RenderTarget == screen && (DFrameBuffer *)screen->Accel2D)
|
||||
{
|
||||
FRenderStyle style = vis->Style.RenderStyle;
|
||||
FRenderStyle style = vis->RenderStyle;
|
||||
style.CheckFuzz();
|
||||
if (style.BlendOp != STYLEOP_Fuzz)
|
||||
{
|
||||
|
@ -1688,18 +1684,18 @@ void R_DrawRemainingPlayerSprites()
|
|||
FColormapStyle colormapstyle;
|
||||
bool usecolormapstyle = false;
|
||||
|
||||
if (vis->Style.colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis->Style.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap)
|
||||
if (vis->colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis->colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap)
|
||||
{
|
||||
// Yuck! There needs to be a better way to store colormaps in the vissprite... :(
|
||||
ptrdiff_t specialmap = (vis->Style.colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
|
||||
ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
|
||||
special = &SpecialColormaps[specialmap];
|
||||
}
|
||||
else if (colormap->Color == PalEntry(255,255,255) &&
|
||||
colormap->Desaturate == 0)
|
||||
{
|
||||
overlay = colormap->Fade;
|
||||
overlay.a = BYTE(((vis->Style.colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS);
|
||||
overlay.a = BYTE(((vis->colormap - colormap->Maps) >> 8) * 255 / NUMCOLORMAPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1707,7 +1703,7 @@ void R_DrawRemainingPlayerSprites()
|
|||
colormapstyle.Color = colormap->Color;
|
||||
colormapstyle.Fade = colormap->Fade;
|
||||
colormapstyle.Desaturate = colormap->Desaturate;
|
||||
colormapstyle.FadeLevel = ((vis->Style.colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS);
|
||||
colormapstyle.FadeLevel = ((vis->colormap - colormap->Maps) >> 8) / float(NUMCOLORMAPS);
|
||||
}
|
||||
screen->DrawTexture(vis->pic,
|
||||
viewwindowx + vispsprites[i].x1,
|
||||
|
@ -1723,7 +1719,7 @@ void R_DrawRemainingPlayerSprites()
|
|||
DTA_ClipRight, viewwindowx + viewwidth,
|
||||
DTA_ClipBottom, viewwindowy + viewheight,
|
||||
DTA_AlphaF, vis->Style.Alpha,
|
||||
DTA_RenderStyle, vis->Style.RenderStyle,
|
||||
DTA_RenderStyle, vis->RenderStyle,
|
||||
DTA_FillColor, vis->FillColor,
|
||||
DTA_SpecialColormap, special,
|
||||
DTA_ColorOverlay, overlay.d,
|
||||
|
@ -1950,7 +1946,7 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
int r1, r2;
|
||||
short topclip, botclip;
|
||||
short *clip1, *clip2;
|
||||
lighttable_t *colormap = spr->Style.colormap;
|
||||
lighttable_t *colormap = spr->colormap;
|
||||
F3DFloor *rover;
|
||||
FDynamicColormap *mybasecolormap;
|
||||
|
||||
|
@ -2014,20 +2010,20 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
// found new values, recalculate
|
||||
if (sec)
|
||||
{
|
||||
INTBOOL invertcolormap = (spr->Style.RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
INTBOOL invertcolormap = (spr->RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
|
||||
if (spr->Style.RenderStyle.Flags & STYLEF_InvertSource)
|
||||
if (spr->RenderStyle.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
invertcolormap = !invertcolormap;
|
||||
}
|
||||
|
||||
// Sprites that are added to the scene must fade to black.
|
||||
if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
||||
if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
||||
{
|
||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
||||
}
|
||||
|
||||
if (spr->Style.RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
if (spr->RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
if (invertcolormap)
|
||||
{ // Fade to white
|
||||
|
@ -2047,16 +2043,16 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
}
|
||||
if (fixedlightlev >= 0)
|
||||
{
|
||||
spr->Style.colormap = mybasecolormap->Maps + fixedlightlev;
|
||||
spr->colormap = mybasecolormap->Maps + fixedlightlev;
|
||||
}
|
||||
else if (!foggy && (spr->renderflags & RF_FULLBRIGHT))
|
||||
{ // full bright
|
||||
spr->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps;
|
||||
spr->colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : mybasecolormap->Maps;
|
||||
}
|
||||
else
|
||||
{ // diminished light
|
||||
spriteshade = LIGHT2SHADE(sec->lightlevel + r_actualextralight);
|
||||
spr->Style.colormap = mybasecolormap->Maps + (GETPALOOKUP(
|
||||
spr->colormap = mybasecolormap->Maps + (GETPALOOKUP(
|
||||
r_SpriteVisibility / MAX(MINZ, (double)spr->depth), spriteshade) << COLORMAPSHIFT);
|
||||
}
|
||||
}
|
||||
|
@ -2205,7 +2201,7 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
|
||||
if (topclip >= botclip)
|
||||
{
|
||||
spr->Style.colormap = colormap;
|
||||
spr->colormap = colormap;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2335,7 +2331,7 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
}
|
||||
if (i == x2)
|
||||
{
|
||||
spr->Style.colormap = colormap;
|
||||
spr->colormap = colormap;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2353,7 +2349,7 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
|
||||
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
|
||||
}
|
||||
spr->Style.colormap = colormap;
|
||||
spr->colormap = colormap;
|
||||
}
|
||||
|
||||
// kg3D:
|
||||
|
@ -2601,21 +2597,21 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
|
|||
|
||||
if (fixedlightlev >= 0)
|
||||
{
|
||||
vis->Style.colormap = map + fixedlightlev;
|
||||
vis->colormap = map + fixedlightlev;
|
||||
}
|
||||
else if (fixedcolormap)
|
||||
{
|
||||
vis->Style.colormap = fixedcolormap;
|
||||
vis->colormap = fixedcolormap;
|
||||
}
|
||||
else if (particle->bright)
|
||||
{
|
||||
vis->Style.colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : map;
|
||||
vis->colormap = (r_fullbrightignoresectorcolor) ? FullNormalLight.Maps : map;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Particles are slightly more visible than regular sprites.
|
||||
vis->ColormapNum = GETPALOOKUP(tiz * r_SpriteVisibility * 0.5, shade);
|
||||
vis->Style.colormap = map + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
vis->colormap = map + (vis->ColormapNum << COLORMAPSHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2650,7 +2646,7 @@ void R_DrawParticle_C (vissprite_t *vis)
|
|||
int spacing;
|
||||
BYTE *dest;
|
||||
DWORD fg;
|
||||
BYTE color = vis->Style.colormap[vis->startfrac];
|
||||
BYTE color = vis->colormap[vis->startfrac];
|
||||
int yl = vis->y1;
|
||||
int ycount = vis->y2 - yl + 1;
|
||||
int x1 = vis->x1;
|
||||
|
|
|
@ -95,6 +95,8 @@ struct vissprite_t
|
|||
BYTE ColormapNum; // Which colormap is rendered (needed for shaded drawer)
|
||||
short renderflags;
|
||||
DWORD Translation; // [RH] for color translation
|
||||
lighttable_t *colormap;
|
||||
FRenderStyle RenderStyle;
|
||||
visstyle_t Style;
|
||||
int CurrentPortalUniq; // [ZZ] to identify the portal that this thing is in. used for clipping.
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
struct VisStyle
|
||||
{
|
||||
bool Invert;
|
||||
float Alpha;
|
||||
int RenderStyle;
|
||||
}
|
||||
|
||||
class Inventory : Actor native
|
||||
{
|
||||
const BLINKTHRESHOLD = (4*32);
|
||||
|
@ -56,6 +63,7 @@ class Inventory : Actor native
|
|||
virtual double GetSpeedFactor() { return 1; }
|
||||
virtual bool GetNoTeleportFreeze() { return false; }
|
||||
virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive) {}
|
||||
virtual void AlterWeaponSprite(VisStyle vis, in out int changed) {}
|
||||
|
||||
native bool GoAway();
|
||||
native void GoAwayAndDie();
|
||||
|
|
|
@ -32,6 +32,12 @@ class Powerup : Inventory native
|
|||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Invulnerable
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
class PowerInvulnerable : Powerup native
|
||||
{
|
||||
Default
|
||||
|
@ -39,6 +45,17 @@ class PowerInvulnerable : Powerup native
|
|||
Powerup.Duration -30;
|
||||
inventory.icon "SPSHLD0";
|
||||
}
|
||||
|
||||
override void AlterWeaponSprite (VisStyle vis, in out int changed)
|
||||
{
|
||||
if (Owner != NULL)
|
||||
{
|
||||
if (Mode == 'Ghost' && !(Owner.bShadow))
|
||||
{
|
||||
vis.Alpha = min(0.25 + Owner.Alpha * 0.75, 1.);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PowerStrength : Powerup native
|
||||
|
@ -51,7 +68,13 @@ class PowerStrength : Powerup native
|
|||
}
|
||||
}
|
||||
|
||||
class PowerInvisibility : Powerup native
|
||||
//===========================================================================
|
||||
//
|
||||
// Invisibility
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
class PowerInvisibility : Powerup
|
||||
{
|
||||
Default
|
||||
{
|
||||
|
@ -60,6 +83,202 @@ class PowerInvisibility : Powerup native
|
|||
Powerup.Strength 80;
|
||||
Powerup.Mode "Fuzzy";
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void InitEffect ()
|
||||
{
|
||||
Super.InitEffect();
|
||||
|
||||
let Owner = self.Owner;
|
||||
if (Owner != NULL)
|
||||
{
|
||||
let savedShadow = Owner.bShadow;
|
||||
let savedGhost = Owner.bGhost;
|
||||
let savedCantSeek = Owner.bCantSeek;
|
||||
Owner.bShadow = bShadow;
|
||||
Owner.bGhost = bGhost;
|
||||
Owner.bCantSeek = bCantSeek;
|
||||
bShadow = savedShadow;
|
||||
bGhost = savedGhost;
|
||||
bCantSeek = savedCantSeek;
|
||||
DoEffect();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: DoEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void DoEffect ()
|
||||
{
|
||||
Super.DoEffect();
|
||||
// Due to potential interference with other PowerInvisibility items
|
||||
// the effect has to be refreshed each tic.
|
||||
double ts = (Strength / 100) * (special1 + 1);
|
||||
|
||||
if (ts > 1.) ts = 1.;
|
||||
let newAlpha = clamp((1. - ts), 0., 1.);
|
||||
int newStyle;
|
||||
switch (Mode)
|
||||
{
|
||||
case 'Fuzzy':
|
||||
newStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case 'Opaque':
|
||||
newStyle = STYLE_Normal;
|
||||
break;
|
||||
case 'Additive':
|
||||
newStyle = STYLE_Add;
|
||||
break;
|
||||
case 'Stencil':
|
||||
newStyle = STYLE_Stencil;
|
||||
break;
|
||||
case 'AddStencil' :
|
||||
newStyle = STYLE_AddStencil;
|
||||
break;
|
||||
case 'TranslucentStencil':
|
||||
newStyle = STYLE_TranslucentStencil;
|
||||
break;
|
||||
case 'None' :
|
||||
case 'Cumulative':
|
||||
case 'Translucent':
|
||||
newStyle = STYLE_Translucent;
|
||||
break;
|
||||
default: // Something's wrong
|
||||
newStyle = STYLE_Normal;
|
||||
newAlpha = 1.;
|
||||
break;
|
||||
}
|
||||
Owner.A_SetRenderStyle(newAlpha, newStyle);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void EndEffect ()
|
||||
{
|
||||
Super.EndEffect();
|
||||
if (Owner != NULL)
|
||||
{
|
||||
Owner.bShadow = bShadow;
|
||||
Owner.bGhost = bGhost;
|
||||
Owner.bCantSeek = bCantSeek;
|
||||
|
||||
Owner.A_SetRenderStyle(1, STYLE_Normal);
|
||||
|
||||
// Check whether there are other invisibility items and refresh their effect.
|
||||
// If this isn't done there will be one incorrectly drawn frame when this
|
||||
// item expires.
|
||||
for(let item = Owner.Inv; item != null; item = item.Inv)
|
||||
{
|
||||
if (item != self && item is 'PowerInvisibility')
|
||||
{
|
||||
item.DoEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: AlterWeaponSprite
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void AlterWeaponSprite (VisStyle vis, in out int changed)
|
||||
{
|
||||
// Blink if the powerup is wearing off
|
||||
if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8))
|
||||
{
|
||||
vis.RenderStyle = STYLE_Normal;
|
||||
vis.Alpha = 1.f;
|
||||
changed = 1;
|
||||
return;
|
||||
}
|
||||
else if (changed == 1)
|
||||
{
|
||||
// something else set the weapon sprite back to opaque but this item is still active.
|
||||
float ts = float((Strength / 100) * (special1 + 1));
|
||||
vis.Alpha = clamp((1. - ts), 0., 1.);
|
||||
switch (Mode)
|
||||
{
|
||||
case 'Fuzzy':
|
||||
vis.RenderStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case 'Opaque':
|
||||
vis.RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
case 'Additive':
|
||||
vis.RenderStyle = STYLE_Add;
|
||||
break;
|
||||
case 'Stencil':
|
||||
vis.RenderStyle = STYLE_Stencil;
|
||||
break;
|
||||
case 'TranslucentStencil':
|
||||
vis.RenderStyle = STYLE_TranslucentStencil;
|
||||
break;
|
||||
case 'AddStencil':
|
||||
vis.RenderStyle = STYLE_AddStencil;
|
||||
break;
|
||||
case 'None':
|
||||
case 'Cumulative':
|
||||
case 'Translucent':
|
||||
default:
|
||||
vis.RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible
|
||||
if ((vis.Alpha < 0.25f && special1 > 0) || (vis.Alpha == 0))
|
||||
{
|
||||
vis.Alpha = clamp((1. - Strength/100.), 0., 1.);
|
||||
vis.invert = true;
|
||||
}
|
||||
changed = -1; // This item is valid so another one shouldn't reset the translucency
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: HandlePickup
|
||||
//
|
||||
// If the player already has the first stage of a cumulative powerup, getting
|
||||
// it again increases the player's alpha. (But shouldn't this be in Use()?)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override bool HandlePickup (Inventory item)
|
||||
{
|
||||
if (Mode == 'Cumulative' && ((Strength * special1) < 1.) && item.GetClass() == GetClass())
|
||||
{
|
||||
let power = Powerup(item);
|
||||
if (power.EffectTics == 0)
|
||||
{
|
||||
power.bPickupGood = true;
|
||||
return true;
|
||||
}
|
||||
// Only increase the EffectTics, not decrease it.
|
||||
// Color also gets transferred only when the new item has an effect.
|
||||
if (power.EffectTics > EffectTics)
|
||||
{
|
||||
EffectTics = power.EffectTics;
|
||||
BlendColor = power.BlendColor;
|
||||
}
|
||||
special1++; // increases power
|
||||
power.bPickupGood = true;
|
||||
return true;
|
||||
}
|
||||
return Super.HandlePickup (item);
|
||||
}
|
||||
}
|
||||
|
||||
class PowerGhost : PowerInvisibility
|
||||
|
|
Loading…
Reference in a new issue