Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ class GlobalData : public SubsystemInterface

DeathTypeFlags m_defaultExcludedDeathTypes;
Bool m_heightAboveTerrainIncludesWater;
Bool m_hideScorchmarksAboveGround;

// the trailing '\' is included!
const AsciiString &getPath_UserData() const { return m_userDataDir; }
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ GlobalData* GlobalData::m_theOriginal = NULL;

{"DefaultExcludedDeathTypes", INI::parseDeathTypeFlagsList, NULL, offsetof(GlobalData, m_defaultExcludedDeathTypes) },
{"HeightAboveTerrainIncludesWater", INI::parseBool, NULL, offsetof(GlobalData, m_heightAboveTerrainIncludesWater) },
{"HideScorchmarksAboveGround", INI::parseBool, NULL, offsetof(GlobalData, m_hideScorchmarksAboveGround) },
{ NULL, NULL, NULL, 0 } // keep this last

};
Expand Down
131 changes: 114 additions & 17 deletions GeneralsMD/Code/GameEngine/Source/GameClient/FXList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,31 @@ class TerrainScorchFXNugget : public FXNugget
{
if (primary)
{
// If scormarks are high above the ground
if (TheGlobalData->m_hideScorchmarksAboveGround && TheTerrainLogic) {
/*PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(primary);
Real groundHeight = 0;
if (layer != LAYER_GROUND) {
TheTerrainLogic->getLayerHeight(primary->x, primary->y, layer);
}
else {
Real waterZ;
Real terrainZ;
if (TheTerrainLogic->isUnderwater(primary->x, primary->y, &waterZ, &terrainZ))
groundHeight = waterZ;
else
groundHeight = terrainZ;
}*/

PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(primary);
if (layer != LAYER_GROUND)
return;

Real groundHeight = TheTerrainLogic->getLayerHeight(primary->x, primary->y, layer);
if (primary->z - groundHeight > m_radius)
return;
}

Int scorch = m_scorch;
if (scorch < 0)
{
Expand Down Expand Up @@ -541,6 +566,21 @@ class TerrainScorchFXNugget : public FXNugget
};
EMPTY_DTOR(TerrainScorchFXNugget)

//-------------------------------------------------------------------------------------------------
static const char* const AllowedSurfaceNames[] =
{
"ALL",
"LAND",
"WATER",
NULL
};

enum AllowedSurfaceType CPP_11(: Int) {
SURFACE_ALL = 0,
SURFACE_LAND,
SURFACE_WATER
};

//-------------------------------------------------------------------------------------------------
class ParticleSystemFXNugget : public FXNugget
{
Expand All @@ -561,6 +601,11 @@ class ParticleSystemFXNugget : public FXNugget
m_createAtGroundHeight = FALSE;
m_useCallersRadius = FALSE;
m_rotateX = m_rotateY = m_rotateZ = 0;

m_maxAllowedHeight = INFINITY;
m_minAllowedHeight = -INFINITY;
// m_createAtWaterHeight = FALSE;
m_allowedSurfaceType = SURFACE_ALL;
}

virtual void doFXPos(const Coord3D *primary, const Matrix3D* primaryMtx, const Real /*primarySpeed*/, const Coord3D * /*secondary*/, const Real overrideRadius ) const
Expand Down Expand Up @@ -623,6 +668,11 @@ class ParticleSystemFXNugget : public FXNugget
{ "AttachToObject", INI::parseBool, NULL, offsetof( ParticleSystemFXNugget, m_attachToObject ) },
{ "CreateAtGroundHeight", INI::parseBool, NULL, offsetof( ParticleSystemFXNugget, m_createAtGroundHeight ) },
{ "UseCallersRadius", INI::parseBool, NULL, offsetof( ParticleSystemFXNugget, m_useCallersRadius ) },
// New height controls
// { "CreateAtWaterHeight", INI::parseBool, NULL, offsetof(ParticleSystemFXNugget, m_createAtWaterHeight) },
{ "MinAllowedHeight", INI::parseReal, NULL, offsetof(ParticleSystemFXNugget, m_minAllowedHeight) },
{ "MaxAllowedHeight", INI::parseReal, NULL, offsetof(ParticleSystemFXNugget, m_maxAllowedHeight) },
{ "AllowedSurface", INI::parseIndexList, AllowedSurfaceNames, offsetof(ParticleSystemFXNugget, m_allowedSurfaceType) },
{ 0, 0, 0, 0 }
};

Expand Down Expand Up @@ -650,6 +700,38 @@ class ParticleSystemFXNugget : public FXNugget
DEBUG_ASSERTCRASH(tmp, ("ParticleSystem %s not found",m_name.str()));
if (tmp)
{
Real groundHeight = 0; // we might need it later

// Evaluate Height and allowed surfaces first.
if ((TheTerrainLogic != NULL) && (m_minAllowedHeight > -INFINITY || m_maxAllowedHeight < INFINITY || m_allowedSurfaceType != SURFACE_ALL || m_createAtGroundHeight)) {
PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(primary);

if (layer != LAYER_GROUND) { // Bridge
if (m_allowedSurfaceType == SURFACE_WATER) return; // No water effects over bridges.
groundHeight = TheTerrainLogic->getLayerHeight(primary->x, primary->y, layer);
}
else { // Ground (Water or Land)
Real waterZ = 0;
Real terrainZ = 0;
if (m_allowedSurfaceType != SURFACE_ALL || TheGlobalData->m_heightAboveTerrainIncludesWater) { // Do water check
Bool isWater = TheTerrainLogic->isUnderwater(primary->x, primary->y, &waterZ, &terrainZ);

if (isWater) {
if (m_allowedSurfaceType == SURFACE_LAND) return;
groundHeight = waterZ;
}
else {
if (m_allowedSurfaceType == SURFACE_WATER) return;
groundHeight = terrainZ;
}
}
}

Real zOffset = primary->z - groundHeight;
if (zOffset < m_minAllowedHeight || zOffset > m_maxAllowedHeight) return;
}


for (Int i = 0; i < m_count; i++ )
{
ParticleSystem *sys = TheParticleSystemManager->createParticleSystem(tmp);
Expand All @@ -661,25 +743,35 @@ class ParticleSystemFXNugget : public FXNugget

newPos.x = primary->x + offset.x + radius * cos(angle);
newPos.y = primary->y + offset.y + radius * sin(angle);
if( m_createAtGroundHeight && TheTerrainLogic )
{
//old way:
//newPos.z = TheTerrainLogic->getGrsoundHeight( newPos.x, newPos.y ) + 1;// The plus one prevents scissoring with terrain
//new way: now we allow bridges in the GroundHeight.
//newer way: include water

PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(&newPos);

if (Real waterZ = 0; TheGlobalData->m_heightAboveTerrainIncludesWater && layer == LAYER_GROUND &&
TheTerrainLogic->isUnderwater(newPos.x, newPos.y, &waterZ)) {
newPos.z = waterZ;
}
else {
newPos.z = TheTerrainLogic->getLayerHeight(newPos.x, newPos.y, layer);
}


if (m_createAtGroundHeight) {
newPos.z = groundHeight + offset.z + m_height.getValue();
}
else
else {
newPos.z = primary->z + offset.z + m_height.getValue();
}

//if( m_createAtGroundHeight && TheTerrainLogic )
//{
// //old way:
// //newPos.z = TheTerrainLogic->getGrsoundHeight( newPos.x, newPos.y ) + 1;// The plus one prevents scissoring with terrain
// //new way: now we allow bridges in the GroundHeight.
// //newer way: include water
// //newest way: include height limits and surface check

// PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(&newPos);
//
// if (Real waterZ = 0; TheGlobalData->m_heightAboveTerrainIncludesWater && layer == LAYER_GROUND &&
// TheTerrainLogic->isUnderwater(newPos.x, newPos.y, &waterZ)) {
// newPos.z = waterZ + offset.z + m_height.getValue();
// }
// else {
// newPos.z = TheTerrainLogic->getLayerHeight(newPos.x, newPos.y, layer) + offset.z + m_height.getValue();
// }
//}
//else
// newPos.z = primary->z + offset.z + m_height.getValue();


if (m_orientToObject && mtx)
Expand Down Expand Up @@ -738,6 +830,11 @@ class ParticleSystemFXNugget : public FXNugget
Bool m_createAtGroundHeight;
Bool m_useCallersRadius;
Bool m_ricochet;

Real m_maxAllowedHeight;
Real m_minAllowedHeight;
//Bool m_createAtWaterHeight;
AllowedSurfaceType m_allowedSurfaceType;
};
EMPTY_DTOR(ParticleSystemFXNugget)

Expand Down