Skip to content

Commit

Permalink
Add support for ECM jammers. ECM jammers will significantly shorten t…
Browse files Browse the repository at this point in the history
…he range

of vision of enemy units and buildings. Not enabled by default. This simplifies
the vision code, merging terrain discovery and object vision, fixing ticket:2917
in the process. Closes ticket:340. Radar detector changed, no longer does
targetting, but allows discovery over 5x longer range instead, and can discover
ECM emissions.
  • Loading branch information
perim committed Oct 16, 2011
1 parent cd6bb3d commit 55a6259
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 216 deletions.
7 changes: 7 additions & 0 deletions data/base/shaders/tcmask.frag
Expand Up @@ -10,6 +10,8 @@ uniform sampler2D Texture2;
uniform vec4 teamcolour;
uniform int tcmask, normalmap;
uniform int fogEnabled;
uniform bool ecmEffect;
uniform float graphicsCycle;

void main(void)
{
Expand Down Expand Up @@ -43,6 +45,11 @@ void main(void)
gl_FragColor = colour * gl_Color;
}

if (ecmEffect)
{
gl_FragColor.a = 0.45 + 0.225 * graphicsCycle;
}

if (fogEnabled > 0)
{
// Calculate linear fog
Expand Down
2 changes: 1 addition & 1 deletion data/mp/stats/ecm.txt
@@ -1,3 +1,3 @@
ZNULLECM,Level All,0,0,0,0,0,0,0,0,DEFAULT,0,0,0
RepairCentre,Level All,0,0,0,0,0,0,GNHREPAR.PIE,0,TURRET,0,0,0
ECM1TurretMk1,Level All,0,0,0,0,0,0,gnmecm1.pie,trmecm2.pie,TURRET,100,4096,1
ECM1TurretMk1,Level All,0,0,0,0,0,0,gnmecm1.pie,trmecm2.pie,TURRET,0,1024,1
7 changes: 7 additions & 0 deletions lib/ivis_opengl/piedraw.cpp
Expand Up @@ -175,6 +175,12 @@ static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELI
}
pie_SetRendMode(REND_OPAQUE);
}
if (pieFlag & pie_ECM)
{
pie_SetRendMode(REND_ALPHA);
light = true;
pie_SetShaderEcmEffect(true);
}

if (light)
{
Expand Down Expand Up @@ -236,6 +242,7 @@ static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELI
{
pie_DeactivateShader();
}
pie_SetShaderEcmEffect(false);

if (pieFlag & pie_BUTTON)
{
Expand Down
23 changes: 22 additions & 1 deletion lib/ivis_opengl/piestate.cpp
Expand Up @@ -39,10 +39,12 @@
// Variables for the coloured mouse cursor
static GLuint shaderProgram[SHADER_MAX];
static GLfloat shaderStretch = 0;
static GLint locTeam, locStretch, locTCMask, locFog, locNormalMap;
static GLint locTeam, locStretch, locTCMask, locFog, locNormalMap, locEcm, locTime;
static SHADER_MODE currentShaderMode = SHADER_NONE;
unsigned int pieStateCount = 0; // Used in pie_GetResetCounts
static RENDER_STATE rendStates;
static GLint ecmState = 0;
static GLfloat timeState = 0.0f;

void rendStatesRendModeHack()
{
Expand Down Expand Up @@ -312,6 +314,21 @@ void pie_DeactivateShader(void)
glUseProgram(0);
}

void pie_SetShaderTime(uint32_t shaderTime)
{
uint32_t base = shaderTime % 1000;
if (base > 500)
{
base = 1000 - base; // cycle
}
timeState = (GLfloat)base / 1000.0f;
}

void pie_SetShaderEcmEffect(bool value)
{
ecmState = (int)value;
}

void pie_SetShaderStretchDepth(float stretch)
{
shaderStretch = stretch;
Expand All @@ -334,6 +351,8 @@ void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpag
locTCMask = glGetUniformLocation(shaderProgram[shaderMode], "tcmask");
locNormalMap = glGetUniformLocation(shaderProgram[shaderMode], "normalmap");
locFog = glGetUniformLocation(shaderProgram[shaderMode], "fogEnabled");
locEcm = glGetUniformLocation(shaderProgram[shaderMode], "ecmEffect");
locTime = glGetUniformLocation(shaderProgram[shaderMode], "graphicsCycle");

// These never change
glUniform1i(locTex0, 0);
Expand All @@ -349,6 +368,8 @@ void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpag
glUniform1i(locTCMask, maskpage != iV_TEX_INVALID);
glUniform1i(locNormalMap, normalpage != iV_TEX_INVALID);
glUniform1i(locFog, rendStates.fog);
glUniform1f(locTime, timeState);
glUniform1i(locEcm, ecmState);

if (maskpage != iV_TEX_INVALID)
{
Expand Down
2 changes: 2 additions & 0 deletions lib/ivis_opengl/piestate.h
Expand Up @@ -88,6 +88,8 @@ bool pie_LoadShaders(void);
void pie_DeactivateShader(void);
void pie_ActivateShader(SHADER_MODE shaderMode, PIELIGHT teamcolour, int maskpage, int normalpage);
void pie_SetShaderStretchDepth(float stretch);
void pie_SetShaderTime(uint32_t shaderTime);
void pie_SetShaderEcmEffect(bool value);

/* Errors control routine */
#define glErrors() \
Expand Down
1 change: 1 addition & 0 deletions lib/ivis_opengl/pietypes.h
Expand Up @@ -47,6 +47,7 @@
#define OLD_TEXTURE_SIZE_FIX 256.0f

//Render style flags for all pie draw functions
#define pie_ECM 0x1
#define pie_TRANSLUCENT 0x2
#define pie_ADDITIVE 0x4
#define pie_FORCE_FOG 0x8
Expand Down
3 changes: 1 addition & 2 deletions src/action.cpp
Expand Up @@ -1971,8 +1971,7 @@ void actionUpdateDroid(DROID *psDroid)
actionTargetTurret(psDroid, psDroid->psActionTarget[0], &psDroid->asWeaps[0]);

// WSS shouldn't get a free pass to hit anything on map
if ((cbSensorDroid(psDroid) && asSensorStats[psDroid->asBits[COMP_SENSOR].nStat].type != SUPER_SENSOR)
|| objRadarDetector(psDroid))
if (cbSensorDroid(psDroid) && asSensorStats[psDroid->asBits[COMP_SENSOR].nStat].type != SUPER_SENSOR)
{
// don't move to the target, just make sure it is visible
// Anyone commenting this out will get a knee capping from John.
Expand Down
43 changes: 1 addition & 42 deletions src/ai.cpp
Expand Up @@ -910,48 +910,7 @@ bool aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget)
}

/* See if there is something in range */
if (radarDetector)
{
BASE_OBJECT *psCurr, *psTemp = NULL;
int tarDist = SDWORD_MAX;

gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS);
psCurr = gridIterate();
while (psCurr != NULL)
{
if ((psCurr->type == OBJ_STRUCTURE || psCurr->type == OBJ_DROID) &&
!aiObjectIsProbablyDoomed(psCurr))
{
if (!aiCheckAlliances(psCurr->player,psObj->player)
&& objActiveRadar(psCurr))
{
// See if in twice *their* sensor range
const int xdiff = psCurr->pos.x - psObj->pos.x;
const int ydiff = psCurr->pos.y - psObj->pos.y;
const unsigned int distSq = xdiff * xdiff + ydiff * ydiff;
const int targetSensor = objSensorRange(psCurr) * 2;
const unsigned int sensorSquared = targetSensor * targetSensor;

if (distSq < sensorSquared && distSq < tarDist)
{
psTemp = psCurr;
tarDist = distSq;
}
}
}
psCurr = gridIterate();
}

if (psTemp)
{
objTrace(psTemp->id, "Targetted by radar detector %d", (int)psObj->id);
objTrace(psObj->id, "Targetting radar %d", (int)psTemp->id);
ASSERT(!psTemp->died, "aiChooseSensorTarget gave us a dead target");
*ppsTarget = psTemp;
return true;
}
}
else if (psObj->type == OBJ_DROID)
if (psObj->type == OBJ_DROID)
{
BASE_OBJECT *psTarget = NULL;

Expand Down
2 changes: 1 addition & 1 deletion src/basedef.h
Expand Up @@ -43,7 +43,7 @@ enum OBJECT_TYPE

struct TILEPOS
{
UBYTE x, y;
UBYTE x, y, type;
};

/*
Expand Down
19 changes: 8 additions & 11 deletions src/component.cpp
Expand Up @@ -524,23 +524,20 @@ static void displayCompObj(DROID *psDroid, bool bButton)
ASSERT_OR_RETURN( , psPropStats != NULL, "invalid propulsion stats pointer");

//set pieflag for button object or ingame object
if ( bButton )
if (bButton)
{
pieFlag = pie_BUTTON;
brightness = WZCOL_WHITE;
}
else
{
pieFlag = 0;
}

if(!bButton)
{
brightness = pal_SetBrightness(psDroid->illumination);
MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y);
pieFlag = pie_SHADOW;
}
else
{
brightness = WZCOL_WHITE;
if (psTile->jammerBits & alliancebits[psDroid->player])
{
pieFlag |= pie_ECM;
}
brightness = pal_SetBrightness(psDroid->illumination);
}

/* set default components transparent */
Expand Down
5 changes: 3 additions & 2 deletions src/display.cpp
Expand Up @@ -2170,11 +2170,12 @@ void dealWithLMB( void )
MAPTILE *psTile = mapTile(mouseTileX, mouseTileY);
uint8_t aux = auxTile(mouseTileX, mouseTileY, selectedPlayer);

CONPRINTF(ConsoleString, (ConsoleString, "%s tile %d, %d [%d, %d] continent(l%d, h%d) level %g illum %d %s %s",
CONPRINTF(ConsoleString, (ConsoleString, "%s tile %d, %d [%d, %d] continent(l%d, h%d) level %g illum %d %s %s w=%d s=%d j=%d",
tileIsExplored(psTile) ? "Explored" : "Unexplored",
mouseTileX, mouseTileY, world_coord(mouseTileX), world_coord(mouseTileY),
(int)psTile->limitedContinent, (int)psTile->hoverContinent, psTile->level, (int)psTile->illumination,
aux & AUXBITS_DANGER ? "danger" : "", aux & AUXBITS_THREAT ? "threat" : ""));
aux & AUXBITS_DANGER ? "danger" : "", aux & AUXBITS_THREAT ? "threat" : "",
(int)psTile->watchers[selectedPlayer], (int)psTile->sensors[selectedPlayer], (int)psTile->jammers[selectedPlayer]));
}

driveDisableTactical();
Expand Down
51 changes: 42 additions & 9 deletions src/display3d.cpp
Expand Up @@ -628,6 +628,9 @@ void draw3DScene( void )
/* What frame number are we on? */
currentGameFrame = frameGetFrameNumber();

// Tell shader system what the time is
pie_SetShaderTime(graphicsTime);

/* Build the drag quad */
if(dragBox3D.status == DRAG_RELEASED)
{
Expand Down Expand Up @@ -1282,8 +1285,14 @@ void renderAnimComponent( const COMPONENT_OBJECT *psObj )
spacetime.pos.z,
-(spacetime.pos.y - player.p.z)
);
SDWORD iPlayer;
int iPlayer, pieFlag = pie_STATIC_SHADOW;
PIELIGHT brightness;
MAPTILE *psTile = worldTile(psParentObj->pos.x, psParentObj->pos.y);

if (psTile->jammerBits & alliancebits[psParentObj->player])
{
pieFlag |= pie_ECM;
}

psParentObj->sDisplay.frameNumber = currentGameFrame;

Expand Down Expand Up @@ -1351,7 +1360,7 @@ void renderAnimComponent( const COMPONENT_OBJECT *psObj )
pie_MatRotZ(-psObj->orientation.y);
pie_MatRotX(-psObj->orientation.x);

pie_Draw3DShape(psObj->psShape, 0, iPlayer, brightness, pie_STATIC_SHADOW, 0);
pie_Draw3DShape(psObj->psShape, 0, iPlayer, brightness, pieFlag, 0);

/* clear stack */
pie_MatEnd();
Expand Down Expand Up @@ -2047,19 +2056,32 @@ static PIELIGHT getBlueprintColour(STRUCT_STATES state)
/// Draw the structures
void renderStructure(STRUCTURE *psStructure)
{
int i, structX, structY, colour, rotation, frame, animFrame, pieFlag, pieFlagData;
int i, structX, structY, colour, rotation, frame, animFrame, pieFlag, pieFlagData, ecmFlag = 0;
PIELIGHT buildingBrightness;
Vector3i dv;
bool bHitByElectronic = false;
bool defensive = false;
iIMDShape *strImd = psStructure->sDisplay.imd;
MAPTILE *psTile = worldTile(psStructure->pos.x, psStructure->pos.y);

if (psStructure->pStructureType->type == REF_WALL || psStructure->pStructureType->type == REF_WALLCORNER
|| psStructure->pStructureType->type == REF_GATE)
{
renderWallSection(psStructure);
return;
}
if (psStructure->visible[selectedPlayer] < UBYTE_MAX && psStructure->visible[selectedPlayer] > 0 && !demoGetStatus())
{
dv.x = psStructure->pos.x - player.p.x;
dv.z = -(psStructure->pos.y - player.p.z);
dv.y = psStructure->pos.z;
pie_MatBegin();
pie_TRANSLATE(dv.x,dv.y,dv.z);
int frame = gameTime / BLIP_ANIM_DURATION + psStructure->id % 8192; // de-sync the blip effect, but don't overflow the int
pie_Draw3DShape(getImdFromIndex(MI_BLIP), frame, 0, WZCOL_WHITE, pie_ADDITIVE, psStructure->visible[selectedPlayer] / 2);
pie_MatEnd();
return;
}
else if (!psStructure->visible[selectedPlayer] && !demoGetStatus())
{
return;
Expand All @@ -2069,6 +2091,11 @@ void renderStructure(STRUCTURE *psStructure)
defensive = true;
}

if (psTile->jammerBits & alliancebits[psStructure->player])
{
ecmFlag = pie_ECM;
}

colour = getPlayerColour(psStructure->player);
animFrame = 0;

Expand Down Expand Up @@ -2129,7 +2156,7 @@ void renderStructure(STRUCTURE *psStructure)
}
else
{
pieFlag = pie_TRANSLUCENT | pie_FORCE_FOG;
pieFlag = pie_TRANSLUCENT | pie_FORCE_FOG | ecmFlag;
pieFlagData = 255;
}
pie_Draw3DShape(psStructure->pStructureType->pBaseIMD, 0, colour, buildingBrightness, pieFlag, pieFlagData);
Expand Down Expand Up @@ -2161,7 +2188,7 @@ void renderStructure(STRUCTURE *psStructure)
}
else
{
pieFlag = pie_STATIC_SHADOW;
pieFlag = pie_STATIC_SHADOW | ecmFlag;
pieFlagData = 0;
}
if (defensive && !structureIsBlueprint(psStructure) && !(strImd->flags & iV_IMD_NOSTRETCH))
Expand Down Expand Up @@ -2223,7 +2250,7 @@ void renderStructure(STRUCTURE *psStructure)
}
else
{
pieFlag = pie_SHADOW;
pieFlag = pie_SHADOW | ecmFlag;
pieFlagData = 0;
}

Expand Down Expand Up @@ -2471,14 +2498,20 @@ void renderDeliveryPoint(FLAG_POSITION *psPosition, bool blueprint)
/// Draw a piece of wall
static bool renderWallSection(STRUCTURE *psStructure)
{
SDWORD structX, structY, height;
int structX, structY, height, ecmFlag = 0;
PIELIGHT brightness;
SDWORD rotation;
Vector3i dv;
int pieFlag, pieFlagData;
MAPTILE *psTile = worldTile(psStructure->pos.x, psStructure->pos.y);

if(psStructure->visible[selectedPlayer] || demoGetStatus())
{
if (psTile->jammerBits & alliancebits[psStructure->player])
{
ecmFlag = pie_ECM;
}

height = psStructure->sDisplay.imd->max.y;
psStructure->sDisplay.frameNumber = currentGameFrame;
/* Get it's x and y coordinates so we don't have to deref. struct later */
Expand Down Expand Up @@ -2521,7 +2554,7 @@ static bool renderWallSection(STRUCTURE *psStructure)
(psStructure->status == SS_BEING_BUILT && psStructure->pStructureType->type == REF_RESOURCE_EXTRACTOR) )
{
pie_Draw3DShape(psStructure->sDisplay.imd, 0, getPlayerColour(psStructure->player),
brightness, pie_HEIGHT_SCALED|pie_SHADOW, structHeightScale(psStructure) * pie_RAISE_SCALE);
brightness, pie_HEIGHT_SCALED|pie_SHADOW|ecmFlag, structHeightScale(psStructure) * pie_RAISE_SCALE);
}
else
{
Expand All @@ -2543,7 +2576,7 @@ static bool renderWallSection(STRUCTURE *psStructure)
}
pieFlagData = 0;
}
pie_Draw3DShape(psStructure->sDisplay.imd, 0, getPlayerColour(psStructure->player), brightness, pieFlag, pieFlagData);
pie_Draw3DShape(psStructure->sDisplay.imd, 0, getPlayerColour(psStructure->player), brightness, pieFlag|ecmFlag, pieFlagData);
}

{
Expand Down

0 comments on commit 55a6259

Please sign in to comment.