Skip to content

Commit f9060a4

Browse files
committed
Chrono Legionnaire and Audio Fixes.
1 parent 28767c0 commit f9060a4

File tree

12 files changed

+262
-79
lines changed

12 files changed

+262
-79
lines changed

Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ class MilesAudioManager : public AudioManager
276276
void initFilters( HSAMPLE sample, const AudioEventRTS *eventInfo );
277277
void initFilters3D( H3DSAMPLE sample, const AudioEventRTS *eventInfo, const Coord3D *pos );
278278

279-
// void handleLoopStopEarly(PlayingAudio* audio);
279+
void handleLoopStopEarly(PlayingAudio* audio);
280280

281281
protected:
282282
ProviderInfo m_provider3D[MAXPROVIDERS];

Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -895,23 +895,54 @@ void MilesAudioManager::playAudioEvent( AudioEventRTS *event )
895895
}
896896

897897
//-------------------------------------------
898-
//void MilesAudioManager::handleLoopStopEarly(PlayingAudio* audio) {
899-
// if (!(audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY)) {
900-
// // We shouldn't be here.
901-
// DEBUG_LOG((">>> handleLoopStopEarly - invalid audio: %s\n", audio->m_audioEventRTS->getEventName().str()));
902-
// return;
903-
// }
904-
//
905-
// // We assume we have a looping sound and jump right to Decay portion
906-
// // -> create new event, and set old one as kill handle
907-
//
908-
// //That's probably a bad idea actually, since it changes the handle. :(
909-
//
910-
// if (audio->m_type == PAT_3DSample) {
911-
//
912-
// // event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
913-
// }
914-
//}
898+
void MilesAudioManager::handleLoopStopEarly(PlayingAudio* audio) {
899+
if (!(audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY)) {
900+
// We shouldn't be here.
901+
DEBUG_LOG((">>> handleLoopStopEarly - invalid audio: %s\n", audio->m_audioEventRTS->getEventName().str()));
902+
return;
903+
}
904+
905+
// We assume we have a looping sound and jump right to Decay portion
906+
// -> create new event, and set old one as kill handle
907+
// This only happens when we already kill the audio, so we don't really need to keep the ref
908+
// to the original AudioEventRTS. It should be safe to create a new one.
909+
910+
/*AudioEventRTS* event = audio->m_audioEventRTS;
911+
event->setHandleToKill(event->getPlayingHandle());
912+
event->setNextPlayPortion(PP_Decay);
913+
914+
playAudioEvent(event);*/
915+
916+
//AudioHandle handleToKill = event->getPlayingHandle();
917+
918+
919+
920+
if (audio->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
921+
audio->m_audioEventRTS->setNextPlayPortion(PP_Sound);
922+
}
923+
audio->m_audioEventRTS->advanceNextPlayPortion();
924+
925+
926+
if (audio->m_audioEventRTS->getNextPlayPortion() != PP_Done) {
927+
if (audio->m_type == PAT_3DSample) {
928+
// don't want to get an additional callback for this sample
929+
AIL_register_3D_EOS_callback(audio->m_3DSample, NULL);
930+
releaseMilesHandles(audio);
931+
closeFile(audio->m_file); // close it so as not to leak it.
932+
933+
audio->m_file = playSample3D(audio->m_audioEventRTS, audio->m_3DSample);
934+
935+
// If we don't have a file now, then we should drop to the stopped status so that
936+
// We correctly close this handle.
937+
if (audio->m_file) {
938+
return;
939+
}
940+
}
941+
}
942+
audio->m_status = PS_Stopped;
943+
944+
945+
}
915946

916947
//-------------------------------------------------------------------------------------------------
917948
void MilesAudioManager::stopAudioEvent( AudioHandle handle )
@@ -971,8 +1002,13 @@ void MilesAudioManager::stopAudioEvent( AudioHandle handle )
9711002

9721003
audio->m_requestStop = true;
9731004
if (audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY) {
974-
// DEBUG_LOG((">>> stopAudioEvent (sounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
975-
notifyOfAudioCompletion((UnsignedInt)(audio->m_sample), PAT_Sample, true);
1005+
DEBUG_LOG((">>> stopAudioEvent (sounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
1006+
1007+
//handleLoopStopEarly(audio);
1008+
1009+
//releaseMilesHandles(audio); // forces stop of this audio
1010+
1011+
//notifyOfAudioCompletion((UnsignedInt)(audio->m_sample), PAT_Sample, true);
9761012
}
9771013

9781014
break;
@@ -993,9 +1029,14 @@ void MilesAudioManager::stopAudioEvent( AudioHandle handle )
9931029
audio->m_requestStop = true;
9941030

9951031
if (audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY) {
996-
// DEBUG_LOG((">>> stopAudioEvent (3DSounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
1032+
DEBUG_LOG((">>> stopAudioEvent (3DSounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
1033+
1034+
handleLoopStopEarly(audio);
1035+
1036+
//releaseMilesHandles(audio); // forces stop of this audio
1037+
//AIL_stop_3D_sample(audio->m_3DSample);
9971038

998-
notifyOfAudioCompletion((UnsignedInt)(audio->m_3DSample), PAT_3DSample, true);
1039+
//notifyOfAudioCompletion((UnsignedInt)(audio->m_3DSample), PAT_3DSample, true);
9991040
}
10001041

10011042
break;
@@ -1573,34 +1614,34 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, Uns
15731614
if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_LOOP) {
15741615

15751616
// Early stop
1576-
if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY && playing->m_requestStop) {
1577-
1578-
if (!isEarlyStop) {
1579-
// We came here from the audio being stopped by other means.
1580-
// To avoid doing things twice, we just return here. I hope this doesn't break things.
1581-
//DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d - isEarlyStop = FALSE\n",
1582-
// playing->m_audioEventRTS->getEventName().str(),
1583-
// playing->m_audioEventRTS->getFilename().str(),
1584-
// playing->m_audioEventRTS->getNextPlayPortion()));
1585-
return;
1586-
}
1587-
1588-
//DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d\n",
1589-
// playing->m_audioEventRTS->getEventName().str(),
1590-
// playing->m_audioEventRTS->getFilename().str(),
1591-
// playing->m_audioEventRTS->getNextPlayPortion()));
1592-
1593-
// How to advance?
1594-
// - Attack -> Decay
1595-
// - Sound -> Decay
1596-
// - Decay -> this shouldn't really happen.
1597-
// We jump from Attack to Sound, so we then advance to Decay
1598-
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
1599-
playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
1600-
}
1601-
}
1617+
//if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY && playing->m_requestStop) {
1618+
1619+
// if (!isEarlyStop) {
1620+
// // We came here from the audio being stopped by other means.
1621+
// // To avoid doing things twice, we just return here. I hope this doesn't break things.
1622+
// DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d - isEarlyStop = FALSE\n",
1623+
// playing->m_audioEventRTS->getEventName().str(),
1624+
// playing->m_audioEventRTS->getFilename().str(),
1625+
// playing->m_audioEventRTS->getNextPlayPortion()));
1626+
// return;
1627+
// }
1628+
1629+
// DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d\n",
1630+
// playing->m_audioEventRTS->getEventName().str(),
1631+
// playing->m_audioEventRTS->getFilename().str(),
1632+
// playing->m_audioEventRTS->getNextPlayPortion()));
1633+
1634+
// // How to advance?
1635+
// // - Attack -> Decay
1636+
// // - Sound -> Decay
1637+
// // - Decay -> this shouldn't really happen.
1638+
// // We jump from Attack to Sound, so we then advance to Decay
1639+
// if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
1640+
// playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
1641+
// }
1642+
//}
16021643
// Normal loop behavior
1603-
else {
1644+
//else {
16041645

16051646
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
16061647
playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
@@ -1615,7 +1656,7 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, Uns
16151656
return;
16161657
}
16171658
}
1618-
}
1659+
//}
16191660
}
16201661

16211662
playing->m_audioEventRTS->advanceNextPlayPortion();

GeneralsMD/Code/GameEngine/Include/GameClient/ParticleSys.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,8 @@ class ParticleSystem : public MemoryPoolObject,
690690
Coord3D m_pos; ///< this is the position to emit at.
691691
Coord3D m_lastPos; ///< this is the previous position we emitted at.
692692

693+
Coord3D m_posOffset; ///< local (to parent transform) offset for created particles
694+
693695
ParticleSystem * m_slaveSystem; ///< if non-NULL, another system this one has control of
694696
ParticleSystemID m_slaveSystemID; ///< id of slave system (if present)
695697

GeneralsMD/Code/GameEngine/Include/GameLogic/AIStateMachine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ class AIStateMachine : public StateMachine
166166
StateID getTemporaryState(void) const {return m_temporaryState?m_temporaryState->getID():INVALID_STATE_ID;}
167167

168168
AIGuardMachine* getGuardMachine( void );
169+
AIGuardRetaliateMachine* getGuardRetaliateMachine( void );
169170

170171
public: // overrides.
171172
virtual StateReturnType updateStateMachine(); ///< run one step of the machine
@@ -1210,6 +1211,10 @@ class AIGuardRetaliateState : public State
12101211
#ifdef STATE_MACHINE_DEBUG
12111212
virtual AsciiString getName() const ;
12121213
#endif
1214+
1215+
// For Teleporter Guard logic
1216+
inline AIGuardRetaliateMachine* const getGuardRetaliateMachine() { return m_guardRetaliateMachine; }
1217+
12131218
protected:
12141219
// snapshot interface
12151220
virtual void crc( Xfer *xfer );

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ChronoDeathBehavior.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,28 @@ class ChronoDeathBehaviorModuleData : public UpdateModuleData
4545
public:
4646
DieMuxData m_dieMuxData;
4747

48-
const ObjectCreationList* m_ocl;
49-
const FXList* m_startFX;
50-
const FXList* m_endFX;
48+
const ObjectCreationList* m_ocl; ///< object created at start
49+
const FXList* m_startFX; ///< FX created at start
50+
const FXList* m_endFX; ///< FX created at end
5151

52-
Real m_startScale;
53-
Real m_endScale;
54-
Real m_startAlpha;
55-
Real m_endAlpha;
52+
// Note AW: These FX are created at start and end if the object matches the kindof.
53+
// This is designed to work in default object.ini
54+
const FXList* m_startFXInfantry;
55+
const FXList* m_startFXVehicle;
56+
const FXList* m_startFXStructure;
5657

57-
Real m_oclScaleFactor;
58+
const FXList* m_endFXInfantry;
59+
const FXList* m_endFXVehicle;
60+
const FXList* m_endFXStructure;
5861

59-
UnsignedInt m_destructionDelay;
62+
Real m_startScale; ///< scale to start with
63+
Real m_endScale; ///< scale at the end
64+
Real m_startAlpha; ///< alpha to start with
65+
Real m_endAlpha; ///< alpha at the end
66+
67+
Real m_oclScaleFactor; ///< base scale of OCL object's model when scaling with object's radius
68+
69+
UnsignedInt m_destructionDelay; ///< total time
6070

6171
ChronoDeathBehaviorModuleData();
6272
static void buildFieldParse(MultiIniFieldParse& p);

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/TeleporterAIUpdate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class TeleporterAIUpdateModuleData : public AIUpdateModuleData
4242
public:
4343
Real m_minDistance;
4444
Real m_disabledDuration;
45+
Real m_minDisabledDuration;
4546

4647
const FXList* m_sourceFX;
4748
const FXList* m_targetFX;

GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,19 @@ AIGuardMachine* AIStateMachine::getGuardMachine(void)
11041104
return NULL;
11051105
}
11061106

1107+
//----------------------------------------------------------------------------------------------------------
1108+
AIGuardRetaliateMachine* AIStateMachine::getGuardRetaliateMachine(void)
1109+
{
1110+
if (getCurrentStateID() == AI_GUARD_RETALIATE) {
1111+
AIGuardRetaliateState* guardState = (AIGuardRetaliateState*)(StateMachine::internalGetState(getCurrentStateID()));
1112+
if (guardState != NULL) {
1113+
return guardState->getGuardRetaliateMachine();
1114+
}
1115+
}
1116+
1117+
return NULL;
1118+
}
1119+
11071120
// State transition conditions ----------------------------------------------------------------------------
11081121
/**
11091122
* Return true if the machine's owner's current weapon's range

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/ChronoDeathBehavior.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
3232
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
33-
#define DEFINE_SLOWDEATHPHASE_NAMES
33+
// #define DEFINE_SLOWDEATHPHASE_NAMES
3434

3535
#include "Common/Thing.h"
3636
#include "Common/ThingTemplate.h"
@@ -71,6 +71,12 @@ ChronoDeathBehaviorModuleData::ChronoDeathBehaviorModuleData()
7171
{
7272
{ "StartFX", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_startFX) },
7373
{ "EndFX", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_endFX) },
74+
{ "StartFXInfantry", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_startFXInfantry) },
75+
{ "StartFXVehicle", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_startFXVehicle) },
76+
{ "StartFXStructure", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_startFXStructure) },
77+
{ "EndFXInfantry", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_endFXInfantry) },
78+
{ "EndFXVehicle", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_endFXVehicle) },
79+
{ "EndFXStructure", INI::parseFXList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_endFXStructure) },
7480
{ "OCL", INI::parseObjectCreationList, NULL, offsetof(ChronoDeathBehaviorModuleData, m_ocl) },
7581
{ "OCLDynamicGeometryScaleFactor", INI::parseReal, NULL, offsetof(ChronoDeathBehaviorModuleData, m_oclScaleFactor) },
7682
{ "StartScale", INI::parseReal, NULL, offsetof(ChronoDeathBehaviorModuleData, m_startScale) },
@@ -126,10 +132,24 @@ UpdateSleepTime ChronoDeathBehavior::update()
126132

127133
if (now >= m_destructionFrame)
128134
{
135+
Real objRadius = obj->getGeometryInfo().getBoundingCircleRadius();
129136
if (d->m_endFX)
130137
{
131-
FXList::doFXObj(d->m_startFX, obj);
138+
FXList::doFXPos(d->m_endFX, obj->getPosition(), NULL, 0, NULL, objRadius);
132139
}
140+
if (d->m_endFXInfantry && obj->isKindOf(KINDOF_INFANTRY))
141+
{
142+
FXList::doFXPos(d->m_endFXInfantry, obj->getPosition(), NULL, 0, NULL, objRadius);
143+
}
144+
if (d->m_endFXVehicle && obj->isKindOf(KINDOF_VEHICLE))
145+
{
146+
FXList::doFXPos(d->m_endFXVehicle, obj->getPosition(), NULL, 0, NULL, objRadius);
147+
}
148+
if (d->m_endFXStructure && obj->isKindOf(KINDOF_STRUCTURE))
149+
{
150+
FXList::doFXPos(d->m_endFXStructure, obj->getPosition(), NULL, 0, NULL, objRadius);
151+
}
152+
133153
TheGameLogic->destroyObject(obj);
134154
return UPDATE_SLEEP_FOREVER;
135155
}
@@ -156,9 +176,22 @@ void ChronoDeathBehavior::beginChronoDeath(const DamageInfo* damageInfo)
156176
draw->setTerrainDecalFadeTarget(0.0f, -0.2f);
157177
}
158178

179+
Real objRadius = obj->getGeometryInfo().getBoundingCircleRadius();
159180
if (d->m_startFX)
160181
{
161-
FXList::doFXObj(d->m_startFX, obj);
182+
FXList::doFXPos(d->m_startFX, obj->getPosition(), NULL, 0, NULL, objRadius);
183+
}
184+
if (d->m_startFXInfantry && obj->isKindOf(KINDOF_INFANTRY))
185+
{
186+
FXList::doFXPos(d->m_startFXInfantry, obj->getPosition(), NULL, 0, NULL, objRadius);
187+
}
188+
if (d->m_startFXVehicle && obj->isKindOf(KINDOF_VEHICLE))
189+
{
190+
FXList::doFXPos(d->m_startFXVehicle, obj->getPosition(), NULL, 0, NULL, objRadius);
191+
}
192+
if (d->m_startFXStructure && obj->isKindOf(KINDOF_STRUCTURE))
193+
{
194+
FXList::doFXPos(d->m_startFXStructure, obj->getPosition(), NULL, 0, NULL, objRadius);
162195
}
163196

164197
if (d->m_ocl)

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,17 +1439,28 @@ void ActiveBody::applyChronoParticleSystems(void)
14391439
ParticleSystem* particleSystem = TheParticleSystemManager->createParticleSystem(chronoEffects);
14401440
if (particleSystem)
14411441
{
1442-
// set the position of the particle system in local object space
1443-
// particleSystem->setPosition(obj->getPosition());
1444-
14451442
// attach particle system to object
14461443
particleSystem->attachToObject(obj);
14471444

1448-
// Scale particle count based on size
1445+
14491446
Real x = obj->getGeometryInfo().getMajorRadius();
1450-
Real y = obj->getGeometryInfo().getMinorRadius();
1447+
Real y;
1448+
if (obj->getGeometryInfo().getGeomType() == GEOMETRY_BOX)
1449+
y = obj->getGeometryInfo().getMinorRadius();
1450+
else
1451+
y = obj->getGeometryInfo().getMajorRadius();
14511452
Real z = obj->getGeometryInfo().getMaxHeightAbovePosition() * 0.5;
14521453
particleSystem->setEmissionBoxHalfSize(x, y, z);
1454+
1455+
// set the position of the particle system in local object space.
1456+
// Apparently even Zero coordinates are needed here.
1457+
Coord3D pos = { 0, 0, 0}; // *obj->getPosition();
1458+
pos.z += z;
1459+
particleSystem->setPosition(&pos);
1460+
1461+
//DEBUG_LOG((">>> applyChronoParticleSystems: pos = {%f, %f, %f}", pos.x, pos.y, pos.z));
1462+
1463+
// Scale particle count based on size ?
14531464
//Real size = x * y;
14541465
//particleSystem->setBurstCountMultiplier(MAX(1.0, sqrt(size * 0.02f))); // these are somewhat tweaked right now
14551466
//particleSystem->setBurstDelayMultiplier(MIN(5.0, sqrt(500.0f / size)));

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Helper/ChronoDamageHelper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ UpdateSleepTime ChronoDamageHelper::update()
5757
{
5858
BodyModuleInterface *body = getObject()->getBodyModule();
5959

60-
DEBUG_LOG(("ChronoDamageHelper::update() - m_healingStepCountdown = %d, healRate = %d, healAmount = %f\n",
61-
m_healingStepCountdown,
62-
body->getChronoDamageHealRate(), body->getChronoDamageHealAmount()));
60+
//DEBUG_LOG(("ChronoDamageHelper::update() - m_healingStepCountdown = %d, healRate = %d, healAmount = %f\n",
61+
// m_healingStepCountdown,
62+
// body->getChronoDamageHealRate(), body->getChronoDamageHealAmount()));
6363

6464
m_healingStepCountdown--;
6565
if( m_healingStepCountdown > 0 )

0 commit comments

Comments
 (0)