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/KindOf.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ enum KindOfType CPP_11(: Int)

KINDOF_TELEPORTER,
KINDOF_SHIPYARD,
KINDOF_NO_MOVE_EFFECTS_ON_WATER,

KINDOF_EXTRA1,
KINDOF_EXTRA2,
Expand Down
4 changes: 4 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/Thing.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,16 @@ class Thing : public MemoryPoolObject
Real getHeightAboveTerrain() const;
Real getHeightAboveTerrainOrWater() const;

Bool isOverWater() const;

Bool isAboveTerrain() const { return getHeightAboveTerrain() > 0.0f; }
Bool isAboveTerrainOrWater() const { return getHeightAboveTerrainOrWater() > 0.0f; }

/** Ground vehicles moving down a slope will get slightly above the terrain.
If we treat this as airborne, then they slide down slopes. This checks whether
they are high enough that we should let them act like they're flying. jba. */
Bool isSignificantlyAboveTerrain() const ;
Bool isSignificantlyAboveTerrainOrWater() const ;

void convertBonePosToWorldPos(const Coord3D* bonePos, const Matrix3D* boneTransform, Coord3D* worldPos, Matrix3D* worldTransform) const;

Expand Down Expand Up @@ -186,6 +189,7 @@ class Thing : public MemoryPoolObject
mutable Coord3D m_cachedDirVector; ///< unit direction vector
mutable Real m_cachedAltitudeAboveTerrain;
mutable Real m_cachedAltitudeAboveTerrainOrWater;
mutable Bool m_cachedIsOverWater;
mutable Int m_cacheFlags;

};
Expand Down
3 changes: 3 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class DrawableLocoInfo : public MemoryPoolObject
TWheelInfo m_wheelInfo; ///< Wheel offset & angle info for a wheeled type locomotor.

DrawableLocoInfo();
void reset();
};

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -605,6 +606,8 @@ class Drawable : public Thing,
Real friend_getExplicitOpacity( void ) { return m_explicitOpacity; }
Real friend_getEffectiveStealthOpacity( void ) { return m_effectiveStealthOpacity; }

void resetPhysicsXform();

protected:

// snapshot methods
Expand Down
6 changes: 5 additions & 1 deletion GeneralsMD/Code/GameEngine/Include/GameClient/TintStatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ enum TintStatus CPP_11(: Int)
TINT_STATUS_TELEPORT_RECOVER, ///< (Chrono Legionnaire -> recover from teleport)
TINT_STATUS_DISABLED_CHRONO, ///< Unit disabled by chrono gun
TINT_STATUS_GAINING_CHRONO_DAMAGE, ///< Unit getting damaged from chrono gun
TINT_STATUS_FORCE_FIELD,
TINT_STATUS_IRON_CURTAIN,
TINT_STATUS_EXTRA1,
TINT_STATUS_EXTRA2,
TINT_STATUS_EXTRA3,
Expand All @@ -34,6 +36,8 @@ enum TintStatus CPP_11(: Int)
TINT_STATUS_EXTRA6,
TINT_STATUS_EXTRA7,
TINT_STATUS_EXTRA8,
TINT_STATUS_EXTRA9,
TINT_STATUS_EXTRA10,

TINT_STATUS_COUNT // Keep this last
};
Expand All @@ -50,4 +54,4 @@ struct DrawableColorTint
typedef BitFlags<TINT_STATUS_COUNT> TintStatusFlags;

// --------
#endif /* __TINTSTATUS_H__ */
#endif /* __TINTSTATUS_H__ */
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class BuffUpdateModuleData : public UpdateModuleData
KindOfMaskType m_forbiddenAffectKindOf; ///< Must be clear on target
Int m_targetsMask; ///< ALLIES, ENEMIES or NEUTRALS
Bool m_isAffectAirborne; ///< Affect Airborne targets
Bool m_requiresAllKindOfs; ///< requires ALL requiredKindOfs or just one of them
UnsignedInt m_buffDuration; ///< How long a hit lasts on target
UnsignedInt m_buffDelay; ///< How often to pulse
Real m_buffRange; ///< How far to affect
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/System/KindOf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ const char* const KindOfMaskType::s_bitNameList[] =

"TELEPORTER",
"SHIPYARD",
"NO_MOVE_EFFECTS_ON_WATER",

"EXTRA1",
"EXTRA2",
Expand Down
20 changes: 20 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/Thing/Thing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,29 @@ Real Thing::getHeightAboveTerrainOrWater() const
if (TheTerrainLogic->isUnderwater(pos->x, pos->y, &waterZ))
{
m_cachedAltitudeAboveTerrainOrWater = pos->z - waterZ;
m_cachedIsOverWater = TRUE;
}
else
{
m_cachedAltitudeAboveTerrainOrWater = getHeightAboveTerrain();
m_cachedIsOverWater = FALSE;
}
m_cacheFlags |= VALID_ALTITUDE_SEALEVEL;
}
return m_cachedAltitudeAboveTerrainOrWater;
}

// ------------------------------------------------------------------------------
Bool Thing::isOverWater() const
{
if (!(m_cacheFlags & VALID_ALTITUDE_SEALEVEL))
{
getHeightAboveTerrainOrWater();
}
return m_cachedIsOverWater;
}


//=============================================================================
/** If we treat this as airborne, then they slide down slopes. This checks whether
they are high enough that we should let them act like they're flying. jba. */
Expand All @@ -341,6 +354,13 @@ Bool Thing::isSignificantlyAboveTerrain() const
// then it's significantly airborne. jba
return (getHeightAboveTerrain() > -(3*3)*TheGlobalData->m_gravity);
}
//-------------------------------------------------------------------------------------------------
Bool Thing::isSignificantlyAboveTerrainOrWater() const
{
// If it's high enough that it will take more than 3 frames to return to the ground,
// then it's significantly airborne. jba
return (getHeightAboveTerrainOrWater() > -(3 * 3) * TheGlobalData->m_gravity);
}


//-------------------------------------------------------------------------------------------------
Expand Down
30 changes: 30 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ static_assert(ARRAY_SIZE(TheDrawableIconNames) == MAX_ICONS + 1, "Incorrect arra


// -----
template<>
const char* const TintStatusFlags::s_bitNameList[] =
{
"NONE",
Expand All @@ -131,6 +132,8 @@ const char* const TintStatusFlags::s_bitNameList[] =
"TELEPORT_RECOVER",
"DISABLED_CHRONO",
"GAINING_CHRONO_DAMAGE",
"FORCE_FIELD",
"IRON_CURTAIN",
"EXTRA1",
"EXTRA2",
"EXTRA3",
Expand All @@ -139,8 +142,12 @@ const char* const TintStatusFlags::s_bitNameList[] =
"EXTRA6",
"EXTRA7",
"EXTRA8",
"EXTRA9",
"EXTRA10",
NULL
};
static_assert(ARRAY_SIZE(TintStatusFlags::s_bitNameList) == TintStatusFlags::NumBits + 1, "Incorrect array size");


/**
* Returns a special DynamicAudioEventInfo which can be used to mark a sound as "no sound".
Expand Down Expand Up @@ -239,6 +246,13 @@ DrawableLocoInfo::~DrawableLocoInfo()
{
}

// ------------------------------------------------------------------------------------------------
void DrawableLocoInfo::reset()
{
*this = DrawableLocoInfo();
}


// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
static const char *drawableIconIndexToName( DrawableIconType iconIndex )
Expand Down Expand Up @@ -1461,6 +1475,22 @@ void Drawable::applyPhysicsXform(Matrix3D* mtx)
}
}

//-------------------------------------------------------------------------------------------------
void Drawable::resetPhysicsXform()
{
if (m_physicsXform != NULL)
{
m_physicsXform->m_totalPitch = 0.0;
m_physicsXform->m_totalRoll = 0.0;
m_physicsXform->m_totalYaw = 0.0;
m_physicsXform->m_totalZ = 0.0;

if (m_locoInfo) {
m_locoInfo->reset();
}
}
}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
Bool Drawable::calcPhysicsXform(PhysicsXformInfo& info)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1909,8 +1909,7 @@ void Locomotor::moveTowardsPositionHover(Object* obj, PhysicsBehavior *physics,
moveTowardsPositionOther(obj, physics, goalPos, onPathDistToGoal, desiredSpeed);

// Only hover locomotors care about their OverWater special effects. (OverWater also affects speed, so this is not a client thing)
Coord3D newPosition = *obj->getPosition();
if( TheTerrainLogic->isUnderwater( newPosition.x, newPosition.y ) )
if( obj->isOverWater() )
{
if( ! getFlag( OVER_WATER ) )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,14 @@ void AIUpdateInterface::chooseGoodLocomotorFromCurrentSet( void )
// Add speed multiplier to loco
if (m_speedMultiplier != 1.0)
m_curLocomotor->applySpeedMultiplier(m_speedMultiplier);

// Reset drawable transforms
if (prevLoco != NULL && prevLoco->getAppearance() != m_curLocomotor->getAppearance()) {
Drawable* draw = getObject()->getDrawable();
if (draw) {
draw->resetPhysicsXform();
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void BuffUpdateModuleData::buildFieldParse(MultiIniFieldParse& p)
static const FieldParse dataFieldParse[] =
{
{ "RequiredAffectKindOf", KindOfMaskType::parseFromINI, NULL, offsetof( BuffUpdateModuleData, m_requiredAffectKindOf ) },
{ "RequiresAllKindOfs", INI::parseBool, NULL, offsetof(BuffUpdateModuleData, m_requiresAllKindOfs) },
{ "ForbiddenAffectKindOf", KindOfMaskType::parseFromINI, NULL, offsetof( BuffUpdateModuleData, m_forbiddenAffectKindOf ) },
{ "AffectsTargets", INI::parseBitString32, TheWeaponAffectsMaskNames, offsetof(BuffUpdateModuleData, m_targetsMask) },
{ "AffectAirborne", INI::parseBool, NULL, offsetof(BuffUpdateModuleData, m_isAffectAirborne) },
Expand Down Expand Up @@ -115,14 +116,21 @@ struct tempBuffData // This is used for iterator to apply buff to contained obje
KindOfMaskType m_requiredMask;
KindOfMaskType m_forbiddenMask;
Bool m_isAffectAirborne;
Bool m_requiresAllKindOfs;
};
void containIteratingDoBuff( Object *passenger, void *voidData)
{
tempBuffData *data = (tempBuffData *)voidData;

if (passenger->isKindOfMulti(data->m_requiredMask, data->m_forbiddenMask)) {
bool match = FALSE;
if (!data->m_requiresAllKindOfs)
match = passenger->isAnyKindOf(data->m_requiredMask) && !passenger->isAnyKindOf(data->m_forbiddenMask);
else
match = passenger->isKindOfMulti(data->m_requiredMask, data->m_forbiddenMask);

if (match) {
if (data->m_isAffectAirborne || !passenger->isAirborneTarget()) {
passenger->applyBuff(data->m_template, data->m_duration, data->m_sourceObj); // TODO: create function in object
passenger->applyBuff(data->m_template, data->m_duration, data->m_sourceObj);
}
}
}
Expand Down Expand Up @@ -170,16 +178,23 @@ UpdateSleepTime BuffUpdate::update( void )
buffData.m_duration = data->m_buffDuration;
buffData.m_requiredMask = data->m_requiredAffectKindOf;
buffData.m_forbiddenMask = data->m_forbiddenAffectKindOf;
buffData.m_requiresAllKindOfs = data->m_requiresAllKindOfs;
buffData.m_isAffectAirborne = data->m_isAffectAirborne;
buffData.m_sourceObj = me; // TODO: Support for projectiles


for( Object *currentObj = iter->first(); currentObj != NULL; currentObj = iter->next() )
{
if( currentObj->isKindOfMulti(data->m_requiredAffectKindOf, data->m_forbiddenAffectKindOf) )
bool match = FALSE;
if (!data->m_requiresAllKindOfs)
match = currentObj->isAnyKindOf(data->m_requiredAffectKindOf) && !currentObj->isAnyKindOf(data->m_forbiddenAffectKindOf);
else
match = currentObj->isKindOfMulti(data->m_requiredAffectKindOf, data->m_forbiddenAffectKindOf);

if (match)
{
if (data->m_isAffectAirborne || !currentObj->isAirborneTarget()) {
currentObj->applyBuff(buffTemp, data->m_buffDuration, me); // TODO
currentObj->applyBuff(buffTemp, data->m_buffDuration, me);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2890,7 +2890,7 @@ Bool Weapon::privateFireWeapon(
WeaponBonus bonus;
computeBonus(sourceObj, extraBonusFlags, bonus);

debug_printWeaponBonus(&bonus, m_template->getName());
// debug_printWeaponBonus(&bonus, m_template->getName());

DEBUG_ASSERTCRASH(getStatus() != OUT_OF_AMMO, ("Hmm, firing weapon that is OUT_OF_AMMO"));
DEBUG_ASSERTCRASH(getStatus() == READY_TO_FIRE, ("Hmm, Weapon is firing more often than should be possible"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ class W3DModelDrawModuleData : public ModuleData

Bool m_showForOwnerOnly; ///< show this model only to the owning player

Bool m_autoSelectObject; ///< show this model only to the owning player
// Bool m_disableMoveEffectsOverWater; ///< disable track marks and tread/wheel anims over water

W3DModelDrawModuleData();
~W3DModelDrawModuleData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,7 @@ void W3DModelDrawModuleData::buildFieldParse(MultiIniFieldParse& p)
{ "IgnoreAnimationSpeedScaling", INI::parseBool, NULL, offsetof(W3DModelDrawModuleData, m_ignoreAnimScaling) },
{ "IgnoreRotation", INI::parseBool, NULL, offsetof(W3DModelDrawModuleData, m_ignoreRotation) },
{ "OnlyVisibleToOwningPlayer", INI::parseBool, NULL, offsetof(W3DModelDrawModuleData, m_showForOwnerOnly) },
//{ "DisableMovementEffectsOverWater", INI::parseBool, NULL, offsetof(W3DModelDrawModuleData, m_disableMoveEffectsOverWater) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
Expand Down Expand Up @@ -3743,13 +3744,13 @@ void W3DModelDraw::reactToTransformChange( const Matrix3D* oldMtx,
Object *obj = getDrawable()->getObject();
const Coord3D* pos = getDrawable()->getPosition();

if ( m_fullyObscuredByShroud || obj->testStatus( OBJECT_STATUS_STEALTHED ) == TRUE )
if ( m_fullyObscuredByShroud || obj->testStatus( OBJECT_STATUS_STEALTHED ) == TRUE || getDrawable()->isDrawableEffectivelyHidden() )
{
m_trackRenderObject->addCapEdgeToTrack(pos->x, pos->y);
}
else
{
if (obj && obj->isSignificantlyAboveTerrain())
if (obj->isSignificantlyAboveTerrain() || (obj->isKindOf(KINDOF_NO_MOVE_EFFECTS_ON_WATER) && obj->isOverWater()))
{
m_trackRenderObject->setAirborne();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ void W3DTankDraw::doDrawModule(const Matrix3D* transformMtx)
m_treadDebrisRight->setBurstCountMultiplier( velMult.z );

//Update movement of treads
if (m_treadCount)
if (m_treadCount && !(obj->isKindOf(KINDOF_NO_MOVE_EFFECTS_ON_WATER) && obj->isOverWater()))
{
PhysicsTurningType turn=physics->getTurning();
Real offset_u;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,19 +537,33 @@ void W3DTankTruckDraw::doDrawModule(const Matrix3D* transformMtx)
if (physics == NULL)
return;

// skip wheel animations - if over water
bool overWater = false;
if (obj->isKindOf(KINDOF_NO_MOVE_EFFECTS_ON_WATER) && obj->isOverWater() && !obj->isSignificantlyAboveTerrainOrWater()) {
overWater = true;
// we need to zero all wheel offsets

}

const Coord3D *vel = physics->getVelocity();
Real speed = physics->getVelocityMagnitude();

const TWheelInfo *wheelInfo = getDrawable()->getWheelInfo(); // note, can return null!
if (wheelInfo && (m_frontLeftTireBone || m_rearLeftTireBone))
{
const Real rotationFactor = getW3DTankTruckDrawModuleData()->m_rotationSpeedMultiplier;
const Real powerslideRotationAddition = getW3DTankTruckDrawModuleData()->m_powerslideRotationAddition * m_isPowersliding;
if (!overWater) {
const Real rotationFactor = getW3DTankTruckDrawModuleData()->m_rotationSpeedMultiplier;
const Real powerslideRotationAddition = getW3DTankTruckDrawModuleData()->m_powerslideRotationAddition * m_isPowersliding;

m_frontWheelRotation += rotationFactor * speed;
m_rearWheelRotation += rotationFactor * (speed + powerslideRotationAddition);
m_frontWheelRotation = WWMath::Normalize_Angle(m_frontWheelRotation);
m_rearWheelRotation = WWMath::Normalize_Angle(m_rearWheelRotation);
}

m_frontWheelRotation += rotationFactor*speed;
m_rearWheelRotation += rotationFactor*(speed+powerslideRotationAddition);
m_frontWheelRotation = WWMath::Normalize_Angle(m_frontWheelRotation);
m_rearWheelRotation = WWMath::Normalize_Angle(m_rearWheelRotation);
// For now, just use the same values for mid wheels -- may want to do independent calcs later...
m_midFrontWheelRotation = m_frontWheelRotation;
m_midRearWheelRotation = m_rearWheelRotation;

Matrix3D wheelXfrm(1);
if (m_frontLeftTireBone)
Expand Down Expand Up @@ -707,7 +721,7 @@ void W3DTankTruckDraw::doDrawModule(const Matrix3D* transformMtx)
m_treadDebrisRight->setBurstCountMultiplier( velMult.z );
#endif
//Update movement of treads
if (m_treadCount)
if (m_treadCount && !(obj->isKindOf(KINDOF_NO_MOVE_EFFECTS_ON_WATER) && obj->isOverWater()))
{
Real offset_u;
Real treadScrollSpeed=getW3DTankTruckDrawModuleData()->m_treadAnimationRate;
Expand Down
Loading