Jump to content

Need help creating an Explosion Sound Alert


RedDobe

Recommended Posts

Hey All. I need some assistance with this. I am trying to create a sound alert once a destructible object is destroyed.

 

The event trigger that I am using is `XEVENTMGR.RegisterForEvent(ThisObj, 'ObjectDestroyed', OnExplosion, ELD_OnStateSubmitted);

 

'Object Destroyed' is triggered on the TakeDamage event (code cut below) in the XComGameState_Destructible class which has all of the information I need to create the alert. I just don't know how to get to it properly.

 

Snipped from TakeDamage in XComGameState_Destructible

{
				// fire an event to notify that this object was destroyed
				KillerUnitState = XComGameState_Unit( `XCOMHISTORY.GetGameStateForObjectID( DamageSource.ObjectID ) );
				`XEVENTMGR.TriggerEvent( 'ObjectDestroyed', KillerUnitState, self, NewGameState );
				bRequiresVisibilityUpdate = true;
			}

			if (Visualizer.IsTargetable( ))
			{
				// Add an environment damage state at our location. This will cause the actual damage to the 
				// destructible actor in the world.
				DamageEvent = XComGameState_EnvironmentDamage( NewGameState.CreateNewStateObject( class'XComGameState_EnvironmentDamage' ) );
				DamageEvent.DEBUG_SourceCodeLocation = "UC: XComGameState_Destructible:TakeEffectDamage";
				DamageEvent.DamageAmount = DamageAmount;
				DamageEvent.DamageTypeTemplateName = 'Explosion';
				DamageEvent.HitLocation = WorldData.GetPositionFromTileCoordinates( TileLocation );
				DamageEvent.DamageTiles.AddItem( TileLocation );
				DamageEvent.DamageCause = DamageSource;
				DamageEvent.DamageSource = DamageEvent.DamageCause;
				DamageEvent.bTargetableDamage = true;
				DamageEvent.DamageTarget = GetReference( );
			}

Here is what I have so far, but Modbuddy is throwing up an error on DamageGameState == none, saying that left type is incompatible with ==.

//My attempt at created hear explosion alerts
function EventListenerReturn OnExplosion(Object EventData, Object EventSource, XComGameState GameState, Name EventID, Object CallbackData)
{
	local XComGameStateHistory History;
	local XComGameState_EnvironmentDamage DamageGameState;
	local TTile SoundTileLocation;
	local AlertAbilityInfo AlertInfo;
	local XComGameState_Unit kUnitState;
	local XComGameState_AIUnitData NewUnitAIState, kAIData;
	local array<StateObjectReference> AliensInRange; // LWS Added
	
	DamageGameState = XComGameState_EnvironmentDamage(EventData);
	if (DamageGameState == none)
	{
		`RedScreen("OnExplosion: no environment damage");
        return ELR_NoInterrupt;
	}
	SoundTileLocation = DamageGameState.DamageTiles[0];
	if (SoundTileLocation == none)
	{
		`RedScreen("OnExplosion: no damage tile found");
        return ELR_NoInterrupt;
	}

	History = `XCOMHISTORY;

	AlertInfo.AlertTileLocation = SoundTileLocation;
	AlertInfo.AlertRadius = 30;
	AlertInfo.AlertUnitSourceID = DamageGameState.DamageCause.ObjectID;
	AlertInfo.AnalyzingHistoryIndex = History.GetCurrentHistoryIndex( ); //NewGameState.HistoryIndex; <- this value is -1.

	// Gather the units in sound range of this explosion.
	class'HelpersYellowAlert'.static.GetAlienUnitsInRange(SoundTileLocation, 30, AliensInRange);

	foreach History.IterateByClassType( class'XComGameState_AIUnitData', kAIData )
	{
		kUnitState = XComGameState_Unit( History.GetGameStateForObjectID( kAIData.m_iUnitObjectID ) );
		if (kUnitState != None && kUnitState.IsAlive( ))
		{
			// LWS Add: Skip units outside of sound range
			if (AliensInRange.Find('ObjectID', kUnitState.ObjectID) < 0)
				continue;
			CleanupAIData = false;
			// LWS: Check to see if we already have ai data for this unit in this game state (alert may already have been propagated to
			// group members).
			NewUnitAIState = XComGameState_AIUnitData(NewGameState.GetGameStateForObjectID(kAIData.ObjectID));
			if (NewUnitAIState == none)
			{
				NewUnitAIState = XComGameState_AIUnitData( NewGameState.CreateStateObject( kAIData.Class, kAIData.ObjectID ) );
				// LWS: This unit will need cleanup if we fail to add the alert.
				CleanupAIData = true;
			}
			if( NewUnitAIState.AddAlertData( kAIData.m_iUnitObjectID, eAC_SeesExplosion, AlertInfo, NewGameState ) )
			{
				NewGameState.AddStateObject(NewUnitAIState);
			}
			else
			{
				// LWS Add: Don't cleanup this AI unit data unless we created it.
				if (CleanupAIData)
				{
					NewGameState.PurgeGameStateForObjectID(NewUnitAIState.ObjectID);
				}
			}
		}
	}

	if( NewGameState.GetNumGameStateObjects() > 0 )
	{
		`GAMERULES.SubmitGameState(NewGameState);
	}
	else
	{
		History.CleanupPendingGameState(NewGameState);
	}

	return ELR_NoInterrupt;
}
Link to comment
Share on other sites

Well I found the problem. I was using the wrong trigger. It turns out there is a trigger for each XComGameState_EnvironmentDamage called 'OnEnvironmentalDamage' that gave me the correct gamestate. This now works and I will be updating the Yellow Alert mod to include explosion alerts.

`XEVENTMGR.RegisterForEvent(ThisObj, 'OnEnvironmentalDamage', OnExplosion, ELD_OnStateSubmitted);

//Create Seesexplosion alerts (truly it is produced by sound but I am using the default eAC_SeesExplosion) 
function EventListenerReturn OnExplosion(Object EventData, Object EventSource, XComGameState GameState, Name EventID, Object CallbackData)
{
	local XComGameStateHistory History;
	local XComGameState_EnvironmentDamage DamageGameState;
	local TTile DamageTileLocation;
	local Name DamageType;
	local bool CanTarget;
	local XComGameState NewGameState;
	local AlertAbilityInfo AlertInfo;
	local XComGameState_Unit kUnitState;
	local XComGameState_AIUnitData NewUnitAIState, kAIData;
	local array<StateObjectReference> AliensInRange; // LWS Added
	local bool CleanupAIData; // LWS Added

	DamageGameState = XComGameState_EnvironmentDamage(EventData);

	CanTarget = DamageGameState.bTargetableDamage;
	DamageType = DamageGameState.DamageTypeTemplateName;
	if(CanTarget && DamageType == 'Explosion')
	{
		`Log("OnExplosion: Can target is "@CanTarget@" and Damage type is "@DamageType);
	}
	else
	{
	return ELR_NoInterrupt;
	}

	DamageTileLocation = DamageGameState.DamageTiles[0];
	`Log("OnExplosion: Damage tile location found at " $DamageTileLocation.X$","@DamageTileLocation.Y$","@DamageTileLocation.Z);	 

	History = `XCOMHISTORY;
	
	// Kick off mass alert to location.
	NewGameState = class'XComGameStateContext_ChangeContainer'.static.CreateChangeState( "Explosion Alert" );

	AlertInfo.AlertTileLocation = DamageTileLocation;
	AlertInfo.AlertRadius = 30;
	AlertInfo.AlertUnitSourceID = DamageGameState.DamageCause.ObjectID;
	AlertInfo.AnalyzingHistoryIndex = History.GetCurrentHistoryIndex( ); //NewGameState.HistoryIndex; <- this value is -1.

	// Gather the units in sound range of this explosion.
	class'HelpersYellowAlert'.static.GetAlienUnitsInRange(DamageTileLocation, 30, AliensInRange);

	foreach History.IterateByClassType( class'XComGameState_AIUnitData', kAIData )
	{
		kUnitState = XComGameState_Unit( History.GetGameStateForObjectID( kAIData.m_iUnitObjectID ) );
		if (kUnitState != None && kUnitState.IsAlive( ))
		{
			// LWS Add: Skip units outside of sound range
			if (AliensInRange.Find('ObjectID', kUnitState.ObjectID) < 0)
				continue;
			CleanupAIData = false;
			// LWS: Check to see if we already have ai data for this unit in this game state (alert may already have been propagated to
			// group members).
			NewUnitAIState = XComGameState_AIUnitData(NewGameState.GetGameStateForObjectID(kAIData.ObjectID));
			if (NewUnitAIState == none)
			{
				NewUnitAIState = XComGameState_AIUnitData( NewGameState.CreateStateObject( kAIData.Class, kAIData.ObjectID ) );
				// LWS: This unit will need cleanup if we fail to add the alert.
				CleanupAIData = true;
			}
			if( NewUnitAIState.AddAlertData( kAIData.m_iUnitObjectID, eAC_SeesExplosion, AlertInfo, NewGameState ) )
			{
				NewGameState.AddStateObject(NewUnitAIState);
			}
			else
			{
				// LWS Add: Don't cleanup this AI unit data unless we created it.
				if (CleanupAIData)
				{
					NewGameState.PurgeGameStateForObjectID(NewUnitAIState.ObjectID);
				}
			}
		}
	}

	if( NewGameState.GetNumGameStateObjects() > 0 )
	{
		`GAMERULES.SubmitGameState(NewGameState);
	}
	else
	{
		History.CleanupPendingGameState(NewGameState);
	}
	return ELR_NoInterrupt;
}
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...