Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,11 @@ class ChinookCombatDropState : public State
Object* rappeller = getPotentialRappeller(obj);
if (rappeller != NULL)
{
#if !RETAIL_COMPATIBLE_CRC
// ChinookAIUpdate::getAiFreeToExit is dependent on this status.
rappeller->setStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_IS_USING_ABILITY));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be added AFTER confirming door is available?
If I understand correctly, when a door is not available, the status will never get cleared (the loop only clears units in the tracking list), so the unit could get stuck with the flag.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The door cannot be reserved unless getAiFreeToExit returns true. If you follow the chain, you'll find reserveDoorForExitisSpecificRiderFreeToExitgetAiFreeToExit. It really only needs the status to be set directly before and to be cleared directly after, but I felt it was not as intuitive. Perhaps it is better to do it this way to reduce complexity and the likelihood of unforeseen consequences.

rappeller->setStatus(OBJECT_STATUS_IS_USING_ABILITY);
exitInterface->reserveDoorForExit();
rappeller->clearStatus(OBJECT_STATUS_IS_USING_ABILITY);

It's unexpected that a door is unavailable when rappelling as indicated by DEBUG_CRASH(("rappeller is not free to exit... what?"));.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see what you mean, so the status has to be set before the door reservation, makes sense. This works, although I really enjoy watching the bugged version 😆 . LGTM

#endif

ExitInterface *exitInterface = obj->getObjectExitInterface();
ExitDoorType exitDoor = exitInterface ? exitInterface->reserveDoorForExit(rappeller->getTemplate(), rappeller) : DOOR_NONE_AVAILABLE;
if(exitDoor != DOOR_NONE_AVAILABLE)
Expand All @@ -598,6 +603,9 @@ class ChinookCombatDropState : public State
DEBUG_CRASH(("rappeller is not free to exit... what?"));
}

#if !RETAIL_COMPATIBLE_CRC
rappeller->clearStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_IS_USING_ABILITY));
#endif
rappeller->setTransformMatrix(&it->dropStartMtx);

AIUpdateInterface* rappellerAI = rappeller ? rappeller->getAIUpdateInterface() : NULL;
Expand Down Expand Up @@ -983,8 +991,17 @@ ObjectID ChinookAIUpdate::getBuildingToNotPathAround() const
//-------------------------------------------------------------------------------------------------
AIFreeToExitType ChinookAIUpdate::getAiFreeToExit(const Object* exiter) const
{
if (m_flightStatus == CHINOOK_LANDED
|| (m_flightStatus == CHINOOK_DOING_COMBAT_DROP && exiter->isKindOf(KINDOF_CAN_RAPPEL)))
if (m_flightStatus == CHINOOK_DOING_COMBAT_DROP && exiter->isKindOf(KINDOF_CAN_RAPPEL))
{
#if !RETAIL_COMPATIBLE_CRC
if (!exiter->testStatus(OBJECT_STATUS_IS_USING_ABILITY))
return WAIT_TO_EXIT;
#endif

return FREE_TO_EXIT;
}

if (m_flightStatus == CHINOOK_LANDED)
return FREE_TO_EXIT;

return WAIT_TO_EXIT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ class ChinookCombatDropState : public State
Object* rappeller = getPotentialRappeller(obj);
if (rappeller != NULL)
{
#if !RETAIL_COMPATIBLE_CRC
// ChinookAIUpdate::getAiFreeToExit is dependent on this status.
rappeller->setStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_IS_USING_ABILITY));
#endif

ExitInterface *exitInterface = obj->getObjectExitInterface();
ExitDoorType exitDoor = exitInterface ? exitInterface->reserveDoorForExit(rappeller->getTemplate(), rappeller) : DOOR_NONE_AVAILABLE;
if(exitDoor != DOOR_NONE_AVAILABLE)
Expand All @@ -599,6 +604,9 @@ class ChinookCombatDropState : public State
DEBUG_CRASH(("rappeller is not free to exit... what?"));
}

#if !RETAIL_COMPATIBLE_CRC
rappeller->clearStatus(MAKE_OBJECT_STATUS_MASK(OBJECT_STATUS_IS_USING_ABILITY));
#endif
rappeller->setTransformMatrix(&it->dropStartMtx);

AIUpdateInterface* rappellerAI = rappeller ? rappeller->getAIUpdateInterface() : NULL;
Expand Down Expand Up @@ -1045,8 +1053,17 @@ ObjectID ChinookAIUpdate::getBuildingToNotPathAround() const
//-------------------------------------------------------------------------------------------------
AIFreeToExitType ChinookAIUpdate::getAiFreeToExit(const Object* exiter) const
{
if (m_flightStatus == CHINOOK_LANDED
|| (m_flightStatus == CHINOOK_DOING_COMBAT_DROP && exiter->isKindOf(KINDOF_CAN_RAPPEL)))
if (m_flightStatus == CHINOOK_DOING_COMBAT_DROP && exiter->isKindOf(KINDOF_CAN_RAPPEL))
{
#if !RETAIL_COMPATIBLE_CRC
if (!exiter->testStatus(OBJECT_STATUS_IS_USING_ABILITY))
return WAIT_TO_EXIT;
#endif

return FREE_TO_EXIT;
}

if (m_flightStatus == CHINOOK_LANDED)
return FREE_TO_EXIT;

return WAIT_TO_EXIT;
Expand Down
Loading