Correct finish time for egg hunt ghosts (#3263)

* Use replay data for ghost karts finish time

* Compute correct finish time for egg hunts replays
This commit is contained in:
Alayan-stk-2 2018-05-22 00:12:16 +02:00 committed by auriamg
parent 04170f5855
commit 175b932b13
4 changed files with 79 additions and 3 deletions

View File

@ -242,7 +242,10 @@ void GhostKart::computeFinishTime()
// In egg hunts, the finish time is the moment at which all egs are collected
if (race_manager->isEggHuntMode())
{
m_finish_time = 0; //FIXME : do a real computation
EasterEggHunt *world = dynamic_cast<EasterEggHunt*>(World::getWorld());
assert(world);
int max_eggs = world->numberOfEggsToFind();
m_finish_time = getTimeForEggs(max_eggs);
}
else // linear races
{
@ -328,4 +331,64 @@ float GhostKart::getTimeForDistance(float distance)
+gc->getTimeAtIndex(upper_frame_index)*(upper_ratio);
return ghost_time;
}
} // getTimeForDIstance
// ----------------------------------------------------------------------------
/** Returns the smallest time at which the kart had the required number of eggs
* Returns -1.0f if none */
float GhostKart::getTimeForEggs(int egg_number)
{
const GhostController* gc =
dynamic_cast<const GhostController*>(getController());
int current_index = gc->getCurrentReplayIndex();
// Second, get the current egg number
int current_eggs = m_all_bonus_info[current_index].m_special_value;
// This determines in which direction we will search a matching frame
bool search_forward = (current_eggs < egg_number);
// This used to compute the time
int lower_frame_index = current_index-1;
unsigned int upper_frame_index = current_index;
// Third, search frame by frame in the good direction
// A modified binary search would be an optimization
while (1)
{
// If we have reached the end of the replay file without finding the
// searched distance, break
if (upper_frame_index >= m_all_bonus_info.size() ||
lower_frame_index < 0 )
break;
// The target distance was reached between those two frames
if (m_all_bonus_info[lower_frame_index].m_special_value < egg_number &&
m_all_bonus_info[upper_frame_index].m_special_value == egg_number)
{
break;
}
if (search_forward)
{
lower_frame_index++;
upper_frame_index++;
}
else
{
lower_frame_index--;
upper_frame_index--;
}
}
float ghost_time;
if (upper_frame_index >= m_all_bonus_info.size() ||
lower_frame_index < 0 )
ghost_time = -1.0f;
else
ghost_time = gc->getTimeAtIndex(upper_frame_index);
return ghost_time;
} // getTimeForEggs

View File

@ -95,6 +95,11 @@ public:
* Returns -1.0f if none */
float getTimeForDistance(float distance);
// ----------------------------------------------------------------------------
/** Returns the smallest time at which the kart had the required number of eggs
* Returns -1.0f if none */
float getTimeForEggs(int egg_number);
// ------------------------------------------------------------------------
virtual void kartIsInRestNow() OVERRIDE {};
// ------------------------------------------------------------------------

View File

@ -248,9 +248,16 @@ void EasterEggHunt::terminateRace()
}
//-----------------------------------------------------------------------------
/** In Easter Egg mode the finish time is just the time the race is over,
* since there are no AI karts.
* since there are no AI karts and no other players, except for ghosts.
*/
float EasterEggHunt::estimateFinishTimeForKart(AbstractKart* kart)
{
// For ghost karts, use the replay data
if (kart->isGhostKart())
{
GhostKart* gk = dynamic_cast<GhostKart*>(kart);
return gk->getGhostFinishTime();
}
return getTime();
} // estimateFinishTimeForKart

View File

@ -64,6 +64,7 @@ public:
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
const int numberOfEggsFound() { return m_eggs_found; }
const int numberOfEggsToFind() { return m_number_of_eggs; }
void updateKartRanks();
void collectedEasterEgg(const AbstractKart *kart);