Skip to content

Commit bbf1894

Browse files
authored
Merge pull request #160 from cortex-command-community/lua-writable-collections
Lua Writable Collections
2 parents b6e5c5d + d574b74 commit bbf1894

23 files changed

+576
-527
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
127127

128128
- `MOSRotating` Lua function `AddWound` now additionally accepts the format `MOSRotating:AddWound(AEmitter* woundToAdd, const Vector& parentOffsetToSet, bool checkGibWoundLimit, bool isEntryWound, bool isExitWound)`, allowing modders to specify added wounds as entry- or exit wounds, for the purpose of not playing multiple burst sounds on the same frame. These new arguments are optional.
129129

130+
- Various performance improvements.
131+
130132
</details>
131133

132134
<details><summary><b>Fixed</b></summary>
@@ -147,6 +149,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
147149

148150
- Fixed an issue where internal Lua functions OriginalDoFile, OriginalLoadFile, and OriginalRequire were polluting the global namespace. They have now been made inaccessible.
149151

152+
- Fixed issue where MOSR `Gib`s, `AEmitter` or `PEmitter` `Emission`s, and MetaMan `Player`s were not correctly accessible from script.
153+
154+
- Fixed a crash on launch when the `SupportedGameVersion` INI property was not set.
155+
150156
</details>
151157

152158
<details><summary><b>Removed</b></summary>
@@ -2677,7 +2683,7 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter
26772683

26782684
- `TDExplosive.ActivatesWhenReleased` now works properly.
26792685

2680-
- Various bug fixed related to all the Attachable and Emitter changes, so they can now me affected reliably and safely with lua.
2686+
- Various bugs fixed related to all the Attachable and Emitter changes, so they can again be affected reliably and safely with lua.
26812687

26822688
- Various minor other things that have gotten lost in the shuffle.
26832689

Source/Activities/AreaEditor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,12 @@ void AreaEditor::Update() {
294294
m_pEditorGUI->SetEditorGUIMode(AreaEditorGUI::PREADDMOVEBOX);
295295
} else {
296296
// Make and name new Area
297-
Scene::Area newArea(m_pNewAreaName->GetText());
297+
Scene::Area* newArea = new Scene::Area(m_pNewAreaName->GetText());
298298
pCurrentScene->m_AreaList.push_back(newArea);
299299
// Set the new area as the active one in the GUI, note we're getting the correct one from the scene, it's a copy of the one passed in
300-
m_pEditorGUI->SetCurrentArea(pCurrentScene->GetArea(newArea.GetName()));
300+
m_pEditorGUI->SetCurrentArea(pCurrentScene->GetArea(newArea->GetName()));
301301
// Update teh picker list of the GUI so we can mousewheel between all the Areas, incl the new one
302-
m_pEditorGUI->UpdatePickerList(newArea.GetName());
302+
m_pEditorGUI->UpdatePickerList(newArea->GetName());
303303
}
304304

305305
// Change mode to start editing the new/newly selected Area

Source/Activities/GibEditor.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,14 @@ void GibEditor::Update() {
400400
m_pEditedObject->Update();
401401

402402
// Make proxy copies of the loaded objects' gib reference instances and place them in the list to be edited
403-
std::list<Gib>* pLoadedGibList = m_pEditedObject->GetGibList();
403+
std::list<Gib*>* pLoadedGibList = m_pEditedObject->GetGibList();
404404
std::list<MovableObject*>* pEditedGibList = m_pEditorGUI->GetPlacedGibs();
405405
MovableObject* pGibCopy = 0;
406406

407407
for (auto gItr = pLoadedGibList->begin(); gItr != pLoadedGibList->end(); ++gItr) {
408-
pGibCopy = dynamic_cast<MovableObject*>((*gItr).GetParticlePreset()->Clone());
408+
pGibCopy = dynamic_cast<MovableObject*>((*gItr)->GetParticlePreset()->Clone());
409409
if (pGibCopy) {
410-
pGibCopy->SetPos(m_pEditedObject->GetPos() + (*gItr).GetOffset());
410+
pGibCopy->SetPos(m_pEditedObject->GetPos() + (*gItr)->GetOffset());
411411
pEditedGibList->push_back(pGibCopy);
412412
}
413413
pGibCopy = 0;
@@ -599,8 +599,8 @@ bool GibEditor::SaveObject(const std::string& saveAsName, bool forceOverwrite) {
599599
}
600600
objectWriter.NewProperty(addObjectType);
601601
m_pEditedObject->Entity::Save(objectWriter);
602-
for (const Gib& gib: *m_pEditedObject->GetGibList()) {
603-
objectWriter.NewPropertyWithValue("AddGib", gib);
602+
for (const Gib* gib: *m_pEditedObject->GetGibList()) {
603+
objectWriter.NewPropertyWithValue("AddGib", *gib);
604604
}
605605
objectWriter.ObjectEnd();
606606
objectWriter.EndWrite();
@@ -626,18 +626,18 @@ void GibEditor::StuffEditedGibs(MOSRotating* pEditedObject) {
626626
return;
627627

628628
// Replace the gibs of the object with the proxies that have been edited in the gui
629-
std::list<Gib>* pObjectGibList = pEditedObject->GetGibList();
629+
std::list<Gib*>* pObjectGibList = pEditedObject->GetGibList();
630630
pObjectGibList->clear();
631631

632632
// Take each proxy object and stuff it into a Gib instance which then gets stuffed into the object to be saved
633633
std::list<MovableObject*>* pProxyGibList = m_pEditorGUI->GetPlacedGibs();
634634
for (std::list<MovableObject*>::iterator gItr = pProxyGibList->begin(); gItr != pProxyGibList->end(); ++gItr) {
635-
Gib newGib;
635+
Gib* newGib;
636636
// Only set the refernce instance directly from the isntanceman. OWNERSHIP IS NOT TRANSFERRED!
637-
newGib.m_GibParticle = dynamic_cast<const MovableObject*>(g_PresetMan.GetEntityPreset((*gItr)->GetClassName(), (*gItr)->GetPresetName(), m_ModuleSpaceID));
638-
if (newGib.m_GibParticle) {
639-
newGib.m_Count = 1;
640-
newGib.m_Offset = (*gItr)->GetPos() - pEditedObject->GetPos();
637+
newGib->m_GibParticle = dynamic_cast<const MovableObject*>(g_PresetMan.GetEntityPreset((*gItr)->GetClassName(), (*gItr)->GetPresetName(), m_ModuleSpaceID));
638+
if (newGib->m_GibParticle) {
639+
newGib->m_Count = 1;
640+
newGib->m_Offset = (*gItr)->GetPos() - pEditedObject->GetPos();
641641
// TODO: do proper velocity calculations here!
642642
// ... actually leave these as 0 and let them be calculated in GibThis
643643
// newGib.m_MinVelocity = (100.0f + 50.0f * NormalRand()) / (*gItr)->GetMass();

Source/Entities/AEmitter.cpp

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ int AEmitter::Create(const AEmitter& reference) {
6464
SetFlash(dynamic_cast<Attachable*>(reference.m_pFlash->Clone()));
6565
}
6666

67-
for (auto itr = reference.m_EmissionList.begin(); itr != reference.m_EmissionList.end(); ++itr) {
68-
m_EmissionList.push_back(*itr);
67+
for (Emission* emission: reference.m_EmissionList) {
68+
m_EmissionList.push_back(static_cast<Emission*>(emission->Clone()));
6969
}
7070
if (reference.m_EmissionSound) {
7171
m_EmissionSound = dynamic_cast<SoundContainer*>(reference.m_EmissionSound->Clone());
@@ -105,8 +105,8 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
105105
StartPropertyList(return Attachable::ReadProperty(propName, reader));
106106

107107
MatchProperty("AddEmission", {
108-
Emission emission;
109-
reader >> emission;
108+
Emission* emission = new Emission();
109+
reader >> *emission;
110110
m_EmissionList.push_back(emission);
111111
});
112112
MatchProperty("EmissionSound", {
@@ -128,8 +128,8 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
128128
float ppm;
129129
reader >> ppm;
130130
// Go through all emissions and set the rate so that it emulates the way it used to work, for mod backwards compatibility.
131-
for (Emission& emission: m_EmissionList) {
132-
emission.m_PPM = ppm / static_cast<float>(m_EmissionList.size());
131+
for (Emission* emission: m_EmissionList) {
132+
emission->m_PPM = ppm / static_cast<float>(m_EmissionList.size());
133133
}
134134
});
135135
MatchProperty("NegativeThrottleMultiplier", { reader >> m_NegativeThrottleMultiplier; });
@@ -140,8 +140,8 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
140140
int burstSize;
141141
reader >> burstSize;
142142
// Go through all emissions and set the rate so that it emulates the way it used to work, for mod backwards compatibility.
143-
for (Emission& emission: m_EmissionList) {
144-
emission.m_BurstSize = std::ceil(static_cast<float>(burstSize) / static_cast<float>(m_EmissionList.size()));
143+
for (Emission* emission: m_EmissionList) {
144+
emission->m_BurstSize = std::ceil(static_cast<float>(burstSize) / static_cast<float>(m_EmissionList.size()));
145145
}
146146
});
147147
MatchProperty("BurstScale", { reader >> m_BurstScale; });
@@ -166,9 +166,9 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
166166
int AEmitter::Save(Writer& writer) const {
167167
Attachable::Save(writer);
168168

169-
for (auto itr = m_EmissionList.begin(); itr != m_EmissionList.end(); ++itr) {
169+
for (Emission* emission: m_EmissionList) {
170170
writer.NewProperty("AddEmission");
171-
writer << *itr;
171+
writer << *emission;
172172
}
173173
writer.NewProperty("EmissionSound");
174174
writer << m_EmissionSound;
@@ -233,21 +233,27 @@ void AEmitter::Destroy(bool notInherited) {
233233
m_EmissionSound->Stop();
234234
}
235235

236+
for (Emission* emission: m_EmissionList) {
237+
delete emission;
238+
}
239+
236240
delete m_EmissionSound;
237241
delete m_BurstSound;
238242
delete m_EndSound;
239243

240244
// m_BurstSound.Stop();
241245

242-
if (!notInherited)
246+
if (!notInherited) {
243247
Attachable::Destroy();
248+
}
244249
Clear();
245250
}
246251

247252
void AEmitter::ResetEmissionTimers() {
248253
m_LastEmitTmr.Reset();
249-
for (auto eItr = m_EmissionList.begin(); eItr != m_EmissionList.end(); ++eItr)
250-
(*eItr).ResetEmissionTimers();
254+
for (Emission* emission: m_EmissionList) {
255+
emission->ResetEmissionTimers();
256+
}
251257
}
252258

253259
void AEmitter::EnableEmission(bool enable) {
@@ -268,22 +274,22 @@ float AEmitter::EstimateImpulse(bool burst) {
268274
float velMin, velMax, velRange, spread;
269275

270276
// Go through all emissions and emit them according to their respective rates
271-
for (auto eItr = m_EmissionList.begin(); eItr != m_EmissionList.end(); ++eItr) {
277+
for (Emission* emission: m_EmissionList) {
272278
// Only check emissions that push the emitter
273-
if ((*eItr).PushesEmitter()) {
274-
float emissions = ((*eItr).GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs();
279+
if (emission->PushesEmitter()) {
280+
float emissions = (emission->GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs();
275281
float scale = 1.0F;
276282
if (burst) {
277-
emissions *= (*eItr).GetBurstSize();
283+
emissions *= emission->GetBurstSize();
278284
scale = m_BurstScale;
279285
}
280286

281-
velMin = (*eItr).GetMinVelocity() * scale;
282-
velRange = ((*eItr).GetMaxVelocity() - (*eItr).GetMinVelocity()) * 0.5F * scale;
283-
spread = (std::max(static_cast<float>(c_PI) - (*eItr).GetSpread(), 0.0F) / c_PI) * scale; // A large spread will cause the forces to cancel eachother out
287+
velMin = emission->GetMinVelocity() * scale;
288+
velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * 0.5F * scale;
289+
spread = (std::max(static_cast<float>(c_PI) - emission->GetSpread(), 0.0F) / c_PI) * scale; // A large spread will cause the forces to cancel eachother out
284290

285291
// Add to accumulative recoil impulse generated, F = m * a.
286-
impulse += (velMin + velRange) * spread * (*eItr).m_pEmission->GetMass() * emissions;
292+
impulse += (velMin + velRange) * spread * emission->m_pEmission->GetMass() * emissions;
287293
}
288294
}
289295

@@ -305,16 +311,16 @@ float AEmitter::EstimateImpulse(bool burst) {
305311

306312
float AEmitter::GetTotalParticlesPerMinute() const {
307313
float totalPPM = 0;
308-
for (const Emission& emission: m_EmissionList) {
309-
totalPPM += emission.m_PPM;
314+
for (const Emission* emission: m_EmissionList) {
315+
totalPPM += emission->m_PPM;
310316
}
311317
return totalPPM;
312318
}
313319

314320
int AEmitter::GetTotalBurstSize() const {
315321
int totalBurstSize = 0;
316-
for (const Emission& emission: m_EmissionList) {
317-
totalBurstSize += emission.m_BurstSize;
322+
for (const Emission* emission: m_EmissionList) {
323+
totalBurstSize += emission->m_BurstSize;
318324
}
319325
return totalBurstSize;
320326
}
@@ -382,8 +388,8 @@ void AEmitter::Update() {
382388
}
383389

384390
// Reset the timers of all emissions so they will start/stop at the correct relative offsets from now
385-
for (Emission& emission: m_EmissionList)
386-
emission.ResetEmissionTimers();
391+
for (Emission* emission: m_EmissionList)
392+
emission->ResetEmissionTimers();
387393
}
388394
// Update the distance attenuation
389395
else if (m_EmissionSound) {
@@ -415,11 +421,11 @@ void AEmitter::Update() {
415421
MovableObject* pParticle = 0;
416422
Vector parentVel, emitVel, pushImpulses;
417423
// Go through all emissions and emit them according to their respective rates
418-
for (Emission& emission: m_EmissionList) {
424+
for (Emission* emission: m_EmissionList) {
419425
// Make sure the emissions only happen between the start time and end time
420-
if (emission.IsEmissionTime()) {
426+
if (emission->IsEmissionTime()) {
421427
// Apply the throttle factor to the emission rate
422-
currentPPM = emission.GetRate() * throttleFactor;
428+
currentPPM = emission->GetRate() * throttleFactor;
423429
int emissionCount = 0;
424430

425431
// Only do all this if the PPM is actually above zero
@@ -428,71 +434,71 @@ void AEmitter::Update() {
428434
SPE = 60.0 / currentPPM;
429435

430436
// Add the last elapsed time to the accumulator
431-
emission.m_Accumulator += m_LastEmitTmr.GetElapsedSimTimeS();
437+
emission->m_Accumulator += m_LastEmitTmr.GetElapsedSimTimeS();
432438

433439
// Now figure how many full emissions can fit in the current accumulator
434-
emissionCount = std::floor(emission.m_Accumulator / SPE);
440+
emissionCount = std::floor(emission->m_Accumulator / SPE);
435441
// Deduct the about to be emitted emissions from the accumulator
436-
emission.m_Accumulator -= emissionCount * SPE;
442+
emission->m_Accumulator -= emissionCount * SPE;
437443

438-
RTEAssert(emission.m_Accumulator >= 0, "Emission accumulator negative!");
444+
RTEAssert(emission->m_Accumulator >= 0, "Emission accumulator negative!");
439445
} else {
440-
emission.m_Accumulator = 0;
446+
emission->m_Accumulator = 0;
441447
}
442448
float scale = 1.0F;
443449
// Add extra emissions if bursting.
444450
if (m_BurstTriggered) {
445-
emissionCount += emission.GetBurstSize() * std::floor(throttleFactor);
451+
emissionCount += emission->GetBurstSize() * std::floor(throttleFactor);
446452
scale = m_BurstScale;
447453
}
448454
emissionCountTotal += emissionCount;
449455
if (emissionCount > 0) {
450-
int extraEmissions = emission.GetParticleCount() - 1;
456+
int extraEmissions = emission->GetParticleCount() - 1;
451457
emissionCount += extraEmissions;
452458
}
453459
pParticle = 0;
454460
emitVel.Reset();
455-
parentVel = pRootParent->GetVel() * emission.InheritsVelocity();
456-
Vector rotationalVel = (((RotateOffset(emission.GetOffset()) + (m_Pos - pRootParent->GetPos())) * pRootParent->GetAngularVel()).GetPerpendicular() / c_PPM) * emission.InheritsVelocity();
461+
parentVel = pRootParent->GetVel() * emission->InheritsVelocity();
462+
Vector rotationalVel = (((RotateOffset(emission->GetOffset()) + (m_Pos - pRootParent->GetPos())) * pRootParent->GetAngularVel()).GetPerpendicular() / c_PPM) * emission->InheritsVelocity();
457463

458464
for (int i = 0; i < emissionCount; ++i) {
459-
velMin = emission.GetMinVelocity() * scale;
460-
velRange = (emission.GetMaxVelocity() - emission.GetMinVelocity()) * scale;
461-
spread = emission.GetSpread() * scale;
465+
velMin = emission->GetMinVelocity() * scale;
466+
velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * scale;
467+
spread = emission->GetSpread() * scale;
462468
// Make a copy after the reference particle
463-
pParticle = dynamic_cast<MovableObject*>(emission.GetEmissionParticlePreset()->Clone());
469+
pParticle = dynamic_cast<MovableObject*>(emission->GetEmissionParticlePreset()->Clone());
464470
// Set up its position and velocity according to the parameters of this.
465471
// Emission point offset not set
466472

467-
if (emission.GetOffset().IsZero()) {
473+
if (emission->GetOffset().IsZero()) {
468474
if (m_EmissionOffset.IsZero()) {
469475
pParticle->SetPos(m_Pos);
470476
} else {
471477
pParticle->SetPos(m_Pos + RotateOffset(m_EmissionOffset));
472478
}
473479
} else {
474-
pParticle->SetPos(m_Pos + RotateOffset(emission.GetOffset()));
480+
pParticle->SetPos(m_Pos + RotateOffset(emission->GetOffset()));
475481
}
476482
// TODO: Optimize making the random angles!")
477483
emitVel.SetXY(velMin + RandomNum(0.0F, velRange), 0.0F);
478484
emitVel.RadRotate(m_EmitAngle.GetRadAngle() + spread * RandomNormalNum());
479485
emitVel = RotateOffset(emitVel);
480486
pParticle->SetVel(parentVel + rotationalVel + emitVel);
481487
pParticle->SetRotAngle(emitVel.GetAbsRadAngle() + (m_HFlipped ? -c_PI : 0));
482-
pParticle->SetAngularVel(pRootParent->GetAngularVel() * emission.InheritsAngularVelocity());
488+
pParticle->SetAngularVel(pRootParent->GetAngularVel() * emission->InheritsAngularVelocity());
483489
pParticle->SetHFlipped(m_HFlipped);
484490

485491
// Scale the particle's lifetime based on life variation and throttle, as long as it's not 0
486492
if (pParticle->GetLifetime() != 0) {
487-
pParticle->SetLifetime(std::max(static_cast<int>(static_cast<float>(pParticle->GetLifetime()) * (1.0F + (emission.GetLifeVariation() * RandomNormalNum()))), 1));
493+
pParticle->SetLifetime(std::max(static_cast<int>(static_cast<float>(pParticle->GetLifetime()) * (1.0F + (emission->GetLifeVariation() * RandomNormalNum()))), 1));
488494
pParticle->SetLifetime(std::max(static_cast<int>(pParticle->GetLifetime() * throttleFactor), 1));
489495
}
490496
pParticle->SetTeam(m_Team);
491497
pParticle->SetIgnoresTeamHits(true);
492498

493499
// Add to accumulative recoil impulse generated, F = m * a
494500
// If enabled, that is
495-
if (emission.PushesEmitter() && (GetParent() || GetMass() > 0)) {
501+
if (emission->PushesEmitter() && (GetParent() || GetMass() > 0)) {
496502
pushImpulses -= emitVel * pParticle->GetMass();
497503
}
498504

Source/Entities/AEmitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ namespace RTE {
367367
static Entity::ClassInfo m_sClass;
368368

369369
// The list of MO instances that get emitted
370-
std::vector<Emission> m_EmissionList;
370+
std::list<Emission*> m_EmissionList;
371371
// Sounds
372372
SoundContainer* m_EmissionSound;
373373
SoundContainer* m_BurstSound;

0 commit comments

Comments
 (0)