diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DroneCarrierContain.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DroneCarrierContain.h index 0d6d620445..39745177d0 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DroneCarrierContain.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DroneCarrierContain.h @@ -12,11 +12,15 @@ #include "GameLogic/Module/TransportContain.h" #include "GameLogic/Module/GarrisonContain.h" + +enum DeathType CPP_11(: Int); + //------------------------------------------------------------------------------------------------- class DroneCarrierContainModuleData: public TransportContainModuleData { public: Real m_launchVelocityBoost; + DeathType m_deathTypeToContained; DroneCarrierContainModuleData(); @@ -52,6 +56,8 @@ class DroneCarrierContain: public TransportContain virtual const ContainedItemsList* getAddOnList() const override; virtual ContainedItemsList* getAddOnList() override; + virtual void onDie(const DamageInfo* damageInfo) override; + // Called from the AI update to reload the contained drones void updateContainedReloadingStatus(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/DroneCarrierContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/DroneCarrierContain.cpp index 73093466c2..29c3363b2a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/DroneCarrierContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/DroneCarrierContain.cpp @@ -5,6 +5,8 @@ // USER INCLUDES ////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine +#define DEFINE_DEATH_NAMES + #include "Common/Player.h" #include "Common/ThingTemplate.h" #include "Common/ThingFactory.h" @@ -19,6 +21,7 @@ #include "GameLogic/Module/StealthUpdate.h" #include "GameLogic/Module/TransportContain.h" #include "GameLogic/Module/DroneCarrierContain.h" +#include "GameLogic/Damage.h" #include "GameLogic/Object.h" #include "GameLogic/Weapon.h" #include "GameLogic/WeaponSetType.h" @@ -27,6 +30,7 @@ DroneCarrierContainModuleData::DroneCarrierContainModuleData() : TransportContainModuleData() { m_launchVelocityBoost = 0.0f; + m_deathTypeToContained = DEATH_DETONATED; } void DroneCarrierContainModuleData::buildFieldParse(MultiIniFieldParse& p) @@ -35,6 +39,7 @@ void DroneCarrierContainModuleData::buildFieldParse(MultiIniFieldParse& p) static const FieldParse dataFieldParse[] = { + { "ContainedUnitsDeathType", INI::parseIndexList, TheDeathNames, offsetof(DroneCarrierContainModuleData, m_deathTypeToContained) }, { "LaunchVelocityBoost", INI::parseReal, NULL, offsetof(DroneCarrierContainModuleData, m_launchVelocityBoost) }, { 0, 0, 0, 0 } }; @@ -244,6 +249,9 @@ void DroneCarrierContain::onRemoving(Object* rider) m_frameExitNotBusy = TheGameLogic->getFrame() + d->m_exitDelay; } +//--------------------------------------------------------------------- +//--------------------------------------------------------------------- + void DroneCarrierContain::onContaining(Object* obj, Bool wasSelected) { TransportContain::onContaining(obj, wasSelected); @@ -262,6 +270,57 @@ void DroneCarrierContain::onContaining(Object* obj, Bool wasSelected) } } +//------------------------------------------------------------------------------------------------- +/** Custom Die callback to apply specific death type. */ +//------------------------------------------------------------------------------------------------- +void DroneCarrierContain::onDie(const DamageInfo* damageInfo) +{ + const DroneCarrierContainModuleData* data = getDroneCarrierContainModuleData(); + + if (!data->m_dieMuxData.isDieApplicable(getObject(), damageInfo)) + return; + + // Note: Using SH fix from OpenContain::processDamageToContained + + ContainedItemsList list; + m_containList.swap(list); + m_containListSize = 0; + + ContainedItemsList::iterator it = list.begin(); + + while (it != list.end()) + { + Object* object = *it; + + DEBUG_ASSERTCRASH(object, ("Contain list must not contain NULL element")); + + if (!object->isEffectivelyDead()) + object->kill(DAMAGE_UNRESISTABLE, data->m_deathTypeToContained); + + if (object->isEffectivelyDead()) + { + onRemoving(object); + object->onRemovedFrom(getObject()); + it = list.erase(it); + } + else + { + ++it; + } + } + + // Swap the list back where it belongs. + m_containList.swap(list); + m_containListSize = (UnsignedInt)m_containList.size(); + + killRidersWhoAreNotFreeToExit(); + removeAllContained(); +} + +//--------------------------------------------------------------------- +//--------------------------------------------------------------------- + + short DroneCarrierContain::getRiderSlot(ObjectID riderID) const { for (size_t i = 0; i < m_contained_units.size(); i++) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/CarrierDroneAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/CarrierDroneAIUpdate.cpp index 08ac57d438..f62826ada4 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/CarrierDroneAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/CarrierDroneAIUpdate.cpp @@ -20,7 +20,8 @@ #include "GameLogic/PartitionManager.h" #include "GameLogic/Module/PhysicsUpdate.h" //#include "GameLogic/TerrainLogic.h" -//#include "GameLogic/Weapon.h" +#include "GameLogic/Weapon.h" +#include "Common/ObjectStatusTypes.h" #include "GameLogic/Module/CarrierDroneAIUpdate.h" // #include "GameLogic/Module/JetAIUpdate.h" @@ -96,7 +97,7 @@ UpdateSleepTime CarrierDroneAIUpdate::update() // Init launch state (check contained status) if (!obj->isContained() && m_isContained && m_launchFrame == 0) { - DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - Start Launch State %d", obj->getID())); + //DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - Start Launch State %d", obj->getID())); obj->setModelConditionState(MODELCONDITION_TAKEOFF); chooseLocomotorSet(data->m_launchingLoco); m_launchFrame = TheGameLogic->getFrame(); @@ -106,6 +107,9 @@ UpdateSleepTime CarrierDroneAIUpdate::update() m_launchingSound.setObjectID(obj->getID()); m_launchingSound.setPlayingHandle(TheAudio->addAudioEvent(&m_launchingSound)); } + + // obj->setStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_NO_ATTACK)); + //obj->getCurrentWeapon()->setPossibleNextShotFrame(m_launchFrame + data->m_launchTime); } m_isContained = obj->isContained(); @@ -113,7 +117,7 @@ UpdateSleepTime CarrierDroneAIUpdate::update() if (m_launchFrame != 0) { UnsignedInt now = TheGameLogic->getFrame(); if (m_launchFrame + data->m_launchTime <= now) { - DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - Stop Launch State %d", obj->getID())); + //DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - Stop Launch State %d", obj->getID())); obj->clearModelConditionState(MODELCONDITION_TAKEOFF); chooseLocomotorSet(LOCOMOTORSET_NORMAL); m_launchFrame = 0; @@ -122,7 +126,14 @@ UpdateSleepTime CarrierDroneAIUpdate::update() { TheAudio->removeAudioEvent(m_launchingSound.getPlayingHandle()); } + + // obj->clearStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_NO_ATTACK)); } + //else { // We are still launching + // if (isAttacking()) { + // return UPDATE_SLEEP_NONE; + // } + //} } @@ -137,7 +148,7 @@ UpdateSleepTime CarrierDroneAIUpdate::update() Real dockingDistSquared = data->m_dockingDistance * data->m_dockingDistance; if (getStateMachine()->getCurrentStateID() == AI_ENTER && getGoalObject() != NULL) { distanceToTargetSquared = ThePartitionManager->getDistanceSquared(obj, getGoalObject(), FROM_CENTER_2D); - DEBUG_LOG(("CarrierDroneAIUpdate::update() - distance = %f", sqrt(distanceToTargetSquared))); + //DEBUG_LOG(("CarrierDroneAIUpdate::update() - distance = %f", sqrt(distanceToTargetSquared))); if (distanceToTargetSquared < dockingDistSquared) { isDocking = true; } @@ -146,7 +157,7 @@ UpdateSleepTime CarrierDroneAIUpdate::update() Locomotor* loco = getCurLocomotor(); if (isDocking && !m_isDocking) { - DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - ENTER LANDING STATE %d", obj->getID())); + //DEBUG_LOG((">>> CarrierDroneAIUpdate::update() - ENTER LANDING STATE %d", obj->getID())); //loco->setMaxSpeed(DOCKING_SPEED); chooseLocomotorSet(data->m_dockingLoco); @@ -166,7 +177,7 @@ UpdateSleepTime CarrierDroneAIUpdate::update() m_isDocking = true; } else if (!isDocking && m_isDocking) { - DEBUG_LOG(("<<< CarrierDroneAIUpdate::update() - EXIT LANDING STATE %d", obj->getID())); + //DEBUG_LOG(("<<< CarrierDroneAIUpdate::update() - EXIT LANDING STATE %d", obj->getID())); obj->clearModelConditionState(MODELCONDITION_LANDING); //loco->setMaxSpeed(loco->getMaxSpeedForCondition(getObject()->getBodyModule()->getDamageState())); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/DroneCarrierSlavedUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/DroneCarrierSlavedUpdate.cpp index 0c754edd79..cc61bc9e3c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/DroneCarrierSlavedUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/DroneCarrierSlavedUpdate.cpp @@ -91,6 +91,8 @@ UpdateSleepTime DroneCarrierSlavedUpdate::update(void) { stopSlavedEffects(); + //TODO: Make the drone crash properly (JetSlowDeath) instead of just dropping + //Let's disable the drone so it crashes instead! //Added special case code in physics falling to ensure death. me->setDisabled(DISABLED_UNMANNED);