Skip to content

Commit

Permalink
Merge branch 'development' into inventory-management
Browse files Browse the repository at this point in the history
  • Loading branch information
Causeless authored Dec 7, 2024
2 parents b29c388 + bbf1894 commit 44b8410
Show file tree
Hide file tree
Showing 23 changed files with 576 additions and 527 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

- `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.

- Various performance improvements.

</details>

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

- Various fixes and improvements to inventory management when dual-wielding or carrying a shield, to stop situations where the actor unexpectedly puts their items away.

- Fixed issue where MOSR `Gib`s, `AEmitter` or `PEmitter` `Emission`s, and MetaMan `Player`s were not correctly accessible from script.

- Fixed a crash on launch when the `SupportedGameVersion` INI property was not set.

</details>

<details><summary><b>Removed</b></summary>
Expand Down Expand Up @@ -2679,7 +2685,7 @@ This can be accessed via the new Lua (R/W) `SettingsMan` property `AIUpdateInter

- `TDExplosive.ActivatesWhenReleased` now works properly.

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

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

Expand Down
6 changes: 3 additions & 3 deletions Source/Activities/AreaEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ void AreaEditor::Update() {
m_pEditorGUI->SetEditorGUIMode(AreaEditorGUI::PREADDMOVEBOX);
} else {
// Make and name new Area
Scene::Area newArea(m_pNewAreaName->GetText());
Scene::Area* newArea = new Scene::Area(m_pNewAreaName->GetText());
pCurrentScene->m_AreaList.push_back(newArea);
// 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
m_pEditorGUI->SetCurrentArea(pCurrentScene->GetArea(newArea.GetName()));
m_pEditorGUI->SetCurrentArea(pCurrentScene->GetArea(newArea->GetName()));
// Update teh picker list of the GUI so we can mousewheel between all the Areas, incl the new one
m_pEditorGUI->UpdatePickerList(newArea.GetName());
m_pEditorGUI->UpdatePickerList(newArea->GetName());
}

// Change mode to start editing the new/newly selected Area
Expand Down
22 changes: 11 additions & 11 deletions Source/Activities/GibEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,14 @@ void GibEditor::Update() {
m_pEditedObject->Update();

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

for (auto gItr = pLoadedGibList->begin(); gItr != pLoadedGibList->end(); ++gItr) {
pGibCopy = dynamic_cast<MovableObject*>((*gItr).GetParticlePreset()->Clone());
pGibCopy = dynamic_cast<MovableObject*>((*gItr)->GetParticlePreset()->Clone());
if (pGibCopy) {
pGibCopy->SetPos(m_pEditedObject->GetPos() + (*gItr).GetOffset());
pGibCopy->SetPos(m_pEditedObject->GetPos() + (*gItr)->GetOffset());
pEditedGibList->push_back(pGibCopy);
}
pGibCopy = 0;
Expand Down Expand Up @@ -599,8 +599,8 @@ bool GibEditor::SaveObject(const std::string& saveAsName, bool forceOverwrite) {
}
objectWriter.NewProperty(addObjectType);
m_pEditedObject->Entity::Save(objectWriter);
for (const Gib& gib: *m_pEditedObject->GetGibList()) {
objectWriter.NewPropertyWithValue("AddGib", gib);
for (const Gib* gib: *m_pEditedObject->GetGibList()) {
objectWriter.NewPropertyWithValue("AddGib", *gib);
}
objectWriter.ObjectEnd();
objectWriter.EndWrite();
Expand All @@ -626,18 +626,18 @@ void GibEditor::StuffEditedGibs(MOSRotating* pEditedObject) {
return;

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

// Take each proxy object and stuff it into a Gib instance which then gets stuffed into the object to be saved
std::list<MovableObject*>* pProxyGibList = m_pEditorGUI->GetPlacedGibs();
for (std::list<MovableObject*>::iterator gItr = pProxyGibList->begin(); gItr != pProxyGibList->end(); ++gItr) {
Gib newGib;
Gib* newGib;
// Only set the refernce instance directly from the isntanceman. OWNERSHIP IS NOT TRANSFERRED!
newGib.m_GibParticle = dynamic_cast<const MovableObject*>(g_PresetMan.GetEntityPreset((*gItr)->GetClassName(), (*gItr)->GetPresetName(), m_ModuleSpaceID));
if (newGib.m_GibParticle) {
newGib.m_Count = 1;
newGib.m_Offset = (*gItr)->GetPos() - pEditedObject->GetPos();
newGib->m_GibParticle = dynamic_cast<const MovableObject*>(g_PresetMan.GetEntityPreset((*gItr)->GetClassName(), (*gItr)->GetPresetName(), m_ModuleSpaceID));
if (newGib->m_GibParticle) {
newGib->m_Count = 1;
newGib->m_Offset = (*gItr)->GetPos() - pEditedObject->GetPos();
// TODO: do proper velocity calculations here!
// ... actually leave these as 0 and let them be calculated in GibThis
// newGib.m_MinVelocity = (100.0f + 50.0f * NormalRand()) / (*gItr)->GetMass();
Expand Down
102 changes: 54 additions & 48 deletions Source/Entities/AEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ int AEmitter::Create(const AEmitter& reference) {
SetFlash(dynamic_cast<Attachable*>(reference.m_pFlash->Clone()));
}

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

MatchProperty("AddEmission", {
Emission emission;
reader >> emission;
Emission* emission = new Emission();
reader >> *emission;
m_EmissionList.push_back(emission);
});
MatchProperty("EmissionSound", {
Expand All @@ -128,8 +128,8 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
float ppm;
reader >> ppm;
// Go through all emissions and set the rate so that it emulates the way it used to work, for mod backwards compatibility.
for (Emission& emission: m_EmissionList) {
emission.m_PPM = ppm / static_cast<float>(m_EmissionList.size());
for (Emission* emission: m_EmissionList) {
emission->m_PPM = ppm / static_cast<float>(m_EmissionList.size());
}
});
MatchProperty("NegativeThrottleMultiplier", { reader >> m_NegativeThrottleMultiplier; });
Expand All @@ -140,8 +140,8 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
int burstSize;
reader >> burstSize;
// Go through all emissions and set the rate so that it emulates the way it used to work, for mod backwards compatibility.
for (Emission& emission: m_EmissionList) {
emission.m_BurstSize = std::ceil(static_cast<float>(burstSize) / static_cast<float>(m_EmissionList.size()));
for (Emission* emission: m_EmissionList) {
emission->m_BurstSize = std::ceil(static_cast<float>(burstSize) / static_cast<float>(m_EmissionList.size()));
}
});
MatchProperty("BurstScale", { reader >> m_BurstScale; });
Expand All @@ -166,9 +166,9 @@ int AEmitter::ReadProperty(const std::string_view& propName, Reader& reader) {
int AEmitter::Save(Writer& writer) const {
Attachable::Save(writer);

for (auto itr = m_EmissionList.begin(); itr != m_EmissionList.end(); ++itr) {
for (Emission* emission: m_EmissionList) {
writer.NewProperty("AddEmission");
writer << *itr;
writer << *emission;
}
writer.NewProperty("EmissionSound");
writer << m_EmissionSound;
Expand Down Expand Up @@ -233,21 +233,27 @@ void AEmitter::Destroy(bool notInherited) {
m_EmissionSound->Stop();
}

for (Emission* emission: m_EmissionList) {
delete emission;
}

delete m_EmissionSound;
delete m_BurstSound;
delete m_EndSound;

// m_BurstSound.Stop();

if (!notInherited)
if (!notInherited) {
Attachable::Destroy();
}
Clear();
}

void AEmitter::ResetEmissionTimers() {
m_LastEmitTmr.Reset();
for (auto eItr = m_EmissionList.begin(); eItr != m_EmissionList.end(); ++eItr)
(*eItr).ResetEmissionTimers();
for (Emission* emission: m_EmissionList) {
emission->ResetEmissionTimers();
}
}

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

// Go through all emissions and emit them according to their respective rates
for (auto eItr = m_EmissionList.begin(); eItr != m_EmissionList.end(); ++eItr) {
for (Emission* emission: m_EmissionList) {
// Only check emissions that push the emitter
if ((*eItr).PushesEmitter()) {
float emissions = ((*eItr).GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs();
if (emission->PushesEmitter()) {
float emissions = (emission->GetRate() / 60.0f) * g_TimerMan.GetDeltaTimeSecs();
float scale = 1.0F;
if (burst) {
emissions *= (*eItr).GetBurstSize();
emissions *= emission->GetBurstSize();
scale = m_BurstScale;
}

velMin = (*eItr).GetMinVelocity() * scale;
velRange = ((*eItr).GetMaxVelocity() - (*eItr).GetMinVelocity()) * 0.5F * scale;
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
velMin = emission->GetMinVelocity() * scale;
velRange = (emission->GetMaxVelocity() - emission->GetMinVelocity()) * 0.5F * scale;
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

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

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

float AEmitter::GetTotalParticlesPerMinute() const {
float totalPPM = 0;
for (const Emission& emission: m_EmissionList) {
totalPPM += emission.m_PPM;
for (const Emission* emission: m_EmissionList) {
totalPPM += emission->m_PPM;
}
return totalPPM;
}

int AEmitter::GetTotalBurstSize() const {
int totalBurstSize = 0;
for (const Emission& emission: m_EmissionList) {
totalBurstSize += emission.m_BurstSize;
for (const Emission* emission: m_EmissionList) {
totalBurstSize += emission->m_BurstSize;
}
return totalBurstSize;
}
Expand Down Expand Up @@ -382,8 +388,8 @@ void AEmitter::Update() {
}

// Reset the timers of all emissions so they will start/stop at the correct relative offsets from now
for (Emission& emission: m_EmissionList)
emission.ResetEmissionTimers();
for (Emission* emission: m_EmissionList)
emission->ResetEmissionTimers();
}
// Update the distance attenuation
else if (m_EmissionSound) {
Expand Down Expand Up @@ -415,11 +421,11 @@ void AEmitter::Update() {
MovableObject* pParticle = 0;
Vector parentVel, emitVel, pushImpulses;
// Go through all emissions and emit them according to their respective rates
for (Emission& emission: m_EmissionList) {
for (Emission* emission: m_EmissionList) {
// Make sure the emissions only happen between the start time and end time
if (emission.IsEmissionTime()) {
if (emission->IsEmissionTime()) {
// Apply the throttle factor to the emission rate
currentPPM = emission.GetRate() * throttleFactor;
currentPPM = emission->GetRate() * throttleFactor;
int emissionCount = 0;

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

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

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

RTEAssert(emission.m_Accumulator >= 0, "Emission accumulator negative!");
RTEAssert(emission->m_Accumulator >= 0, "Emission accumulator negative!");
} else {
emission.m_Accumulator = 0;
emission->m_Accumulator = 0;
}
float scale = 1.0F;
// Add extra emissions if bursting.
if (m_BurstTriggered) {
emissionCount += emission.GetBurstSize() * std::floor(throttleFactor);
emissionCount += emission->GetBurstSize() * std::floor(throttleFactor);
scale = m_BurstScale;
}
emissionCountTotal += emissionCount;
if (emissionCount > 0) {
int extraEmissions = emission.GetParticleCount() - 1;
int extraEmissions = emission->GetParticleCount() - 1;
emissionCount += extraEmissions;
}
pParticle = 0;
emitVel.Reset();
parentVel = pRootParent->GetVel() * emission.InheritsVelocity();
Vector rotationalVel = (((RotateOffset(emission.GetOffset()) + (m_Pos - pRootParent->GetPos())) * pRootParent->GetAngularVel()).GetPerpendicular() / c_PPM) * emission.InheritsVelocity();
parentVel = pRootParent->GetVel() * emission->InheritsVelocity();
Vector rotationalVel = (((RotateOffset(emission->GetOffset()) + (m_Pos - pRootParent->GetPos())) * pRootParent->GetAngularVel()).GetPerpendicular() / c_PPM) * emission->InheritsVelocity();

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

if (emission.GetOffset().IsZero()) {
if (emission->GetOffset().IsZero()) {
if (m_EmissionOffset.IsZero()) {
pParticle->SetPos(m_Pos);
} else {
pParticle->SetPos(m_Pos + RotateOffset(m_EmissionOffset));
}
} else {
pParticle->SetPos(m_Pos + RotateOffset(emission.GetOffset()));
pParticle->SetPos(m_Pos + RotateOffset(emission->GetOffset()));
}
// TODO: Optimize making the random angles!")
emitVel.SetXY(velMin + RandomNum(0.0F, velRange), 0.0F);
emitVel.RadRotate(m_EmitAngle.GetRadAngle() + spread * RandomNormalNum());
emitVel = RotateOffset(emitVel);
pParticle->SetVel(parentVel + rotationalVel + emitVel);
pParticle->SetRotAngle(emitVel.GetAbsRadAngle() + (m_HFlipped ? -c_PI : 0));
pParticle->SetAngularVel(pRootParent->GetAngularVel() * emission.InheritsAngularVelocity());
pParticle->SetAngularVel(pRootParent->GetAngularVel() * emission->InheritsAngularVelocity());
pParticle->SetHFlipped(m_HFlipped);

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

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

Expand Down
2 changes: 1 addition & 1 deletion Source/Entities/AEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ namespace RTE {
static Entity::ClassInfo m_sClass;

// The list of MO instances that get emitted
std::vector<Emission> m_EmissionList;
std::list<Emission*> m_EmissionList;
// Sounds
SoundContainer* m_EmissionSound;
SoundContainer* m_BurstSound;
Expand Down
Loading

0 comments on commit 44b8410

Please sign in to comment.