Skip to content

Commit

Permalink
Implemented new ECM visual effect.
Browse files Browse the repository at this point in the history
An EMP disruption effect similar to a burst of TV static while an ECM blast is active has been implemented. The effect will occur regardless of who is triggering the ECM, be it player or NPC. It can be disabled by setting the key "ecm-visual-fx" to NO in the user preferences file.
  • Loading branch information
AnotherCommander authored Nov 28, 2024
1 parent 222d325 commit 10e222e
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 7 deletions.
1 change: 1 addition & 0 deletions Doc/CHANGELOG.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ General:
confusion.
* Updated the wormhole cloud effect.
* Mouse flight sensitivity made configurable by editing the preferences file.
* Implemented new ECM visual effect.

Expansion Pack Development:
===========================
Expand Down
25 changes: 25 additions & 0 deletions Resources/Shaders/oolite-final-hdr.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,25 @@ vec3 CRT(sampler2D inImage, vec2 inCoords)
}
// ------------------------------------------------------------------------------------------

// =======================================================================================
// CRTBadSignal - original at https://www.shadertoy.com/view/ltV3z1
// =======================================================================================
vec3 CRTBadSignal(sampler2D inImage, vec2 inCoords)
{
vec2 uv = inCoords;
float t = uTime;
float fx = 0.001 + 25.0 * abs(sin(t) / 10.0) - mod(1.0 + t, 7.0);
const float s = 50.0; // noise intensity
float x = (floor(uv.x * 300.0)) + (floor(uv.y * 300.0)) * (t * 0.1);
vec4 dtv = vec4(mod((mod(x, 2.0) + 1.0) * (mod(x, 0.0) + 0.0), 0.01) - 0.005) * s;
vec3 col = clamp(vec3(0.1, 0.1, 0.1) + dtv.xyz / fx, vec3(0.0), vec3(0.1));

col.xyz += texture(inImage,uv).xyz;

return col;
}
// ------------------------------------------------------------------------------------------


// =======================================================================================
// FXAA - original at https://www.shadertoy.com/view/MdyyRt
Expand Down Expand Up @@ -716,6 +735,12 @@ void main()
hdrColor *= exposure;
break;
case 8:
hdrColor = CRTBadSignal(scene, TexCoords);
bloomColor = CRT(bloomBlur, TexCoords); // yes CRT, not a typo
if(bloom) hdrColor += bloomColor;
hdrColor *= exposure;
break;
case 9:
hdrColor = gravLens(scene, TexCoords);
bloomColor = gravLens(bloomBlur, TexCoords);
if(bloom) hdrColor += bloomColor;
Expand Down
24 changes: 24 additions & 0 deletions Resources/Shaders/oolite-final.fragment
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,24 @@ vec3 CRT(sampler2D inImage, vec2 inCoords)
}
// ------------------------------------------------------------------------------------------

// =======================================================================================
// CRTBadSignal - original at https://www.shadertoy.com/view/ltV3z1
// =======================================================================================
vec3 CRTBadSignal(sampler2D inImage, vec2 inCoords)
{
vec2 uv = inCoords;
float t = uTime;
float fx = 0.001 + 25.0 * abs(sin(t) / 10.0) - mod(1.0 + t, 7.0);
const float s = 50.0; // noise intensity
float x = (floor(uv.x * 300.0)) + (floor(uv.y * 300.0 )) * (t * 0.1);
vec4 dtv = vec4(mod((mod(x, 2.0) + 1.0) * (mod(x, 0.0) + 0.0), 0.01) - 0.005) * s;
vec3 col = clamp(vec3(0.1, 0.1, 0.1) + dtv.xyz / fx, vec3(0.0), vec3(0.1));

col.xyz += texture(inImage,uv).xyz;

return col;
}
// ------------------------------------------------------------------------------------------

// =======================================================================================
// FXAA - original at https://www.shadertoy.com/view/MdyyRt
Expand Down Expand Up @@ -533,6 +551,12 @@ void main()
hdrColor *= exposure;
break;
case 8:
hdrColor = CRTBadSignal(scene, TexCoords);
bloomColor = CRT(bloomBlur, TexCoords); // yes CRT, not a typo
if(bloom) hdrColor += bloomColor;
hdrColor *= exposure;
break;
case 9:
hdrColor = gravLens(scene, TexCoords);
bloomColor = gravLens(bloomBlur, TexCoords);
if(bloom) hdrColor += bloomColor;
Expand Down
44 changes: 40 additions & 4 deletions src/Core/Entities/PlayerEntity.m
Original file line number Diff line number Diff line change
Expand Up @@ -2725,6 +2725,8 @@ - (void) doBookkeeping:(double) delta_t
STAGE_TRACKING_BEGIN

double speed_delta = SHIP_THRUST_FACTOR * thrust;

static BOOL gettingInterference = NO;

OOSunEntity *sun = [UNIVERSE sun];
double external_temp = 0;
Expand Down Expand Up @@ -2819,6 +2821,29 @@ - (void) doBookkeeping:(double) delta_t
ecm_in_operation = NO;
}
}

// ecm interference visual effect
if ([UNIVERSE useShaders] && [UNIVERSE ECMVisualFXEnabled])
{
// we want to start and stop the effect exactly once, not start it
// or stop it on every frame
if ([self scannerFuzziness] > 0.0)
{
if (!gettingInterference)
{
[UNIVERSE setCurrentPostFX:OO_POSTFX_CRTBADSIGNAL];
gettingInterference = YES;
}
}
else
{
if (gettingInterference)
{
[UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
gettingInterference = NO;
}
}
}

// Energy Banks and Shields

Expand Down Expand Up @@ -3930,11 +3955,18 @@ - (void) performDockingUpdates:(OOTimeDelta)delta_t
{
[self docked]; // bookkeeping for docking
}

// if cloak or ecm visual effects are playing while docking, terminate them
[UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
if ([UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
}


- (void) performDeadUpdates:(OOTimeDelta)delta_t
{
[UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
if ([UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];

[self gameOverFadeToBW];

if ([self shotTime] > kDeadResetTime)
Expand Down Expand Up @@ -6055,7 +6087,7 @@ - (void) deactivateCloakingDevice
if (![self hasCloakingDevice]) return;

[super deactivateCloakingDevice];
[UNIVERSE setCurrentPostFX:[UNIVERSE colorblindMode]];
[UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
[UNIVERSE addMessage:DESC(@"cloak-off") forCount:2];
[self playCloakingDeviceOff];
}
Expand All @@ -6066,11 +6098,15 @@ - (void) deactivateCloakingDevice
- (double) scannerFuzziness
{
double fuzz = 0.0;

/* Fuzziness from ECM bursts */
double since = [UNIVERSE getTime] - last_ecm_time;
if (since < SCANNER_ECM_FUZZINESS)
if (last_ecm_time > 0.0)
{
fuzz += (SCANNER_ECM_FUZZINESS - since) * (SCANNER_ECM_FUZZINESS - since) * 500.0;
double since = [UNIVERSE getTime] - last_ecm_time;
if (since < SCANNER_ECM_FUZZINESS)
{
fuzz += (SCANNER_ECM_FUZZINESS - since) * (SCANNER_ECM_FUZZINESS - since) * 500.0;
}
}
/* Other causes could go here */

Expand Down
7 changes: 7 additions & 0 deletions src/Core/Universe.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ enum
OO_POSTFX_GRAYSCALE,
OO_POSTFX_OLDMOVIE,
OO_POSTFX_CRT,
OO_POSTFX_CRTBADSIGNAL,
OO_POSTFX_ENDOFLIST // keep this for last
};

Expand Down Expand Up @@ -313,6 +314,8 @@ enum
#ifndef NDEBUG
double timeAccelerationFactor;
#endif

BOOL ECMVisualFXEnabled;

NSMutableArray *activeWormholes;

Expand Down Expand Up @@ -380,6 +383,7 @@ enum

- (int) currentPostFX;
- (void) setCurrentPostFX: (int) newCurrentPostFX;
- (void) terminatePostFX:(int) postFX;

- (id)initWithGameView:(MyOpenGLView *)gameView;

Expand Down Expand Up @@ -644,6 +648,9 @@ enum
- (double) timeAccelerationFactor;
- (void) setTimeAccelerationFactor:(double)newTimeAccelerationFactor;

- (BOOL) ECMVisualFXEnabled;
- (void) setECMVisualFXEnabled:(BOOL)isEnabled;

- (void) filterSortedLists;

///////////////////////////////////////
Expand Down
29 changes: 26 additions & 3 deletions src/Core/Universe.m
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,15 @@ - (void) setCurrentPostFX: (int) newCurrentPostFX
_currentPostFX = newCurrentPostFX;
}


- (void) terminatePostFX:(int)postFX
{
if ([self currentPostFX] == postFX)
{
[self setCurrentPostFX:[self colorblindMode]];
}
}

- (int) nextColorblindMode:(int) index
{
if (++index > OO_POSTFX_COLORBLINDNESS_TRITAN)
Expand Down Expand Up @@ -745,7 +754,9 @@ - (id) initWithGameView:(MyOpenGLView *)inGameView
OOLog(@"MSAA.setup", @"Multisample anti-aliasing %@requested.", [inGameView msaa] ? @"" : @"not ");
[inGameView setFov:OOClamp_0_max_f([prefs oo_floatForKey:@"fov-value" defaultValue:57.2f], MAX_FOV_DEG) fromFraction:NO];
if ([inGameView fov:NO] < MIN_FOV_DEG) [inGameView setFov:MIN_FOV_DEG fromFraction:NO];


[self setECMVisualFXEnabled:[prefs oo_boolForKey:@"ecm-visual-fx" defaultValue:YES]];

// Set up speech synthesizer.
#if OOLITE_SPEECH_SYNTH
#if OOLITE_MAC_OS_X
Expand Down Expand Up @@ -4802,8 +4813,8 @@ - (BOOL) viewFrustumIntersectsSphereAt:(Vector)position withRadius:(GLfloat)radi
- (void) drawUniverse
{
int currentPostFX = [self currentPostFX];
BOOL hudSeparateRenderPass = [self useShaders] && (currentPostFX == OO_POSTFX_NONE || (currentPostFX == OO_POSTFX_CLOAK && [self colorblindMode] == OO_POSTFX_NONE));
NSSize viewSize = [gameView viewSize];
BOOL hudSeparateRenderPass = [self useShaders] && (currentPostFX == OO_POSTFX_NONE || ((currentPostFX == OO_POSTFX_CLOAK || currentPostFX == OO_POSTFX_CRTBADSIGNAL) && [self colorblindMode] == OO_POSTFX_NONE));
NSSize viewSize = [gameView viewSize];
OOLog(@"universe.profile.draw", @"%@", @"Begin draw");

if (!no_update)
Expand Down Expand Up @@ -7383,6 +7394,18 @@ - (void) setTimeAccelerationFactor:(double)newTimeAccelerationFactor
#endif


- (BOOL) ECMVisualFXEnabled
{
return ECMVisualFXEnabled;
}


- (void) setECMVisualFXEnabled:(BOOL)isEnabled
{
ECMVisualFXEnabled = isEnabled;
}


- (void) filterSortedLists
{
/*
Expand Down

0 comments on commit 10e222e

Please sign in to comment.