Allow auto-save replay when specified in time trial mode.
It will disable AI when recording, also it will only save if the race is completed, ie no one gave up or all events fit in max frame recorded.
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
|
||||
|
||||
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
|
||||
<header id="name" height="5%" width="80%" align="center" text_align="center"/>
|
||||
<header id="name" height="7%" width="80%" align="center" text_align="center"/>
|
||||
|
||||
<spacer width="1" height="5%"/>
|
||||
<spacer width="1" height="1%"/>
|
||||
|
||||
<box width="100%" height="40%" padding="10" layout="horizontal-row">
|
||||
<!-- Left pane -->
|
||||
@@ -49,8 +49,8 @@
|
||||
</div>
|
||||
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<box width="100%" height="25%" padding="15" layout="vertical-row">
|
||||
<spacer width="1" height="1%"/>
|
||||
<box width="100%" height="33%" padding="15" layout="vertical-row">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="lap-text" proportion="1" I18N="In the track info screen" text="Number of laps" text_align="right"/>
|
||||
<spacer width="40"/>
|
||||
@@ -78,9 +78,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<spacer width="1" height="2%"/>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label id="record-race-text" proportion="1" I18N="In the track info screen" text="Record the race for ghost replay" text_align="right"/>
|
||||
<spacer width="40"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row">
|
||||
<div width="50%" height="fit" text-align="center" layout="vertical-row" >
|
||||
<checkbox id="record" align="center"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<spacer width="1" height="1%"/>
|
||||
</box>
|
||||
<spacer width="1" height="5%"/>
|
||||
<spacer width="1" height="1%"/>
|
||||
<buttonbar id="buttons" height="15%" width="100%" align="center">
|
||||
<icon-button id="start" width="64" height="64" icon="gui/green_check.png"
|
||||
I18N="In the track info screen" text="Start Race"/>
|
||||
|
||||
@@ -368,7 +368,7 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
if(world && value)
|
||||
{
|
||||
if(control_is_pressed && ReplayRecorder::get())
|
||||
ReplayRecorder::get()->Save();
|
||||
ReplayRecorder::get()->save();
|
||||
else
|
||||
history->Save();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ GhostController::GhostController(AbstractKart *kart,
|
||||
StateManager::ActivePlayer *player)
|
||||
: Controller(kart, player)
|
||||
{
|
||||
m_kart = kart;
|
||||
} // GhostController
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -53,10 +53,10 @@ public:
|
||||
virtual void updateWeight() {};
|
||||
// ------------------------------------------------------------------------
|
||||
/** No physics for ghost kart. */
|
||||
virtual void applyEngineForce (float force) {}
|
||||
virtual void applyEngineForce (float force) {};
|
||||
// ------------------------------------------------------------------------
|
||||
// Not needed to create any physics for a ghost kart.
|
||||
virtual void createPhysics() {}
|
||||
virtual void createPhysics() {};
|
||||
// ------------------------------------------------------------------------
|
||||
const float getSuspensionLength(int index, int wheel) const
|
||||
{ return m_all_physic_info[index].m_suspension_length[wheel]; }
|
||||
|
||||
@@ -279,7 +279,7 @@ void World::reset()
|
||||
race_manager->reset();
|
||||
// Make sure to overwrite the data from the previous race.
|
||||
if(!history->replayHistory()) history->initRecording();
|
||||
if(ReplayRecorder::get()) ReplayRecorder::get()->init();
|
||||
if(race_manager->willRecordRace()) ReplayRecorder::get()->init();
|
||||
|
||||
// Reset all data structures that depend on number of karts.
|
||||
irr_driver->reset();
|
||||
@@ -970,8 +970,7 @@ void World::update(float dt)
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("World::update (sub-updates)", 0x20, 0x7F, 0x00);
|
||||
history->update(dt);
|
||||
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
|
||||
if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
|
||||
if(race_manager->willRecordRace()) ReplayRecorder::get()->update(dt);
|
||||
if(history->replayHistory()) dt=history->getNextDelta();
|
||||
WorldStatus::update(dt);
|
||||
if (m_script_engine) m_script_engine->update(dt);
|
||||
|
||||
@@ -76,6 +76,7 @@ RaceManager::RaceManager()
|
||||
m_started_from_overworld = false;
|
||||
m_have_kart_last_position_on_overworld = false;
|
||||
setReverseTrack(false);
|
||||
setRecordRace(false);
|
||||
setTrack("jungle");
|
||||
m_default_ai_list.clear();
|
||||
setNumPlayers(0);
|
||||
|
||||
@@ -350,6 +350,7 @@ private:
|
||||
/** Determines if saved GP should be continued or not*/
|
||||
bool m_continue_saved_gp;
|
||||
|
||||
bool m_will_record_race;
|
||||
public:
|
||||
RaceManager();
|
||||
~RaceManager();
|
||||
@@ -697,6 +698,16 @@ public:
|
||||
{
|
||||
return m_kart_last_position_on_overworld;
|
||||
} // getKartLastPositionOnOverworld
|
||||
// ------------------------------------------------------------------------
|
||||
void setRecordRace(bool record)
|
||||
{
|
||||
m_will_record_race = record;
|
||||
} // setRecordRace
|
||||
// ------------------------------------------------------------------------
|
||||
bool willRecordRace() const
|
||||
{
|
||||
return m_will_record_race;
|
||||
} // willRecordRace
|
||||
|
||||
}; // RaceManager
|
||||
|
||||
|
||||
@@ -60,18 +60,6 @@ void ReplayPlay::reset()
|
||||
}
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates all ghost karts.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ReplayPlay::update(float dt)
|
||||
{
|
||||
// First update all ghost karts
|
||||
for(unsigned int i=0; i<(unsigned int)m_ghost_karts.size(); i++)
|
||||
m_ghost_karts[i].update(dt);
|
||||
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads the basic (ghost karts, reverse track) info in the replay file,
|
||||
* required by race manager.
|
||||
|
||||
@@ -48,7 +48,6 @@ private:
|
||||
~ReplayPlay();
|
||||
void readKartData(FILE *fd, char *next_line);
|
||||
public:
|
||||
void update(float dt);
|
||||
void reset();
|
||||
void load();
|
||||
void loadBasicInfo();
|
||||
|
||||
@@ -55,6 +55,8 @@ ReplayRecorder::~ReplayRecorder()
|
||||
*/
|
||||
void ReplayRecorder::init()
|
||||
{
|
||||
m_complete_replay = false;
|
||||
m_incorrect_replay = false;
|
||||
m_transform_events.clear();
|
||||
m_physic_info.clear();
|
||||
m_kart_replay_event.clear();
|
||||
@@ -81,19 +83,14 @@ void ReplayRecorder::init()
|
||||
#endif
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Resets all ghost karts back to start position.
|
||||
*/
|
||||
void ReplayRecorder::reset()
|
||||
{
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Saves the current replay data.
|
||||
* \param dt Time step size.
|
||||
*/
|
||||
void ReplayRecorder::update(float dt)
|
||||
{
|
||||
if (m_incorrect_replay || m_complete_replay) return;
|
||||
|
||||
const World *world = World::getWorld();
|
||||
unsigned int num_karts = world->getNumKarts();
|
||||
|
||||
@@ -104,6 +101,9 @@ void ReplayRecorder::update(float dt)
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
const AbstractKart *kart = world->getKart(i);
|
||||
// Don't record give-up race
|
||||
if (kart->isEliminated()) return;
|
||||
|
||||
if (kart->isGhostKart()) continue;
|
||||
#ifdef DEBUG
|
||||
m_count++;
|
||||
@@ -126,6 +126,7 @@ void ReplayRecorder::update(float dt)
|
||||
sprintf(buffer, "Can't store more events for kart %s.",
|
||||
kart->getIdent().c_str());
|
||||
Log::warn("ReplayRecorder", buffer);
|
||||
m_incorrect_replay = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -173,13 +174,25 @@ void ReplayRecorder::update(float dt)
|
||||
r->m_on_nitro = nitro;
|
||||
r->m_on_zipper = zipper;
|
||||
} // for i
|
||||
|
||||
if (world->getPhase() == World::RESULT_DISPLAY_PHASE && !m_complete_replay)
|
||||
{
|
||||
m_complete_replay = true;
|
||||
save();
|
||||
}
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Saves the replay data stored in the internal data structures.
|
||||
*/
|
||||
void ReplayRecorder::Save()
|
||||
void ReplayRecorder::save()
|
||||
{
|
||||
if (m_incorrect_replay || !m_complete_replay)
|
||||
{
|
||||
Log::warn("ReplayRecorder", "Incomplete replay file will not be saved.");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%d frames, %d removed because of frequency compression\n",
|
||||
m_count, m_count_skipped_time);
|
||||
@@ -194,6 +207,7 @@ void ReplayRecorder::Save()
|
||||
|
||||
Log::info("ReplayRecorder", "Replay saved in '%s'.\n", getReplayFilename().c_str());
|
||||
|
||||
fprintf(fd, "reverse: %d\n", (int)race_manager->getReverseTrack());
|
||||
World *world = World::getWorld();
|
||||
unsigned int num_karts = world->getNumKarts();
|
||||
for (unsigned int real_karts = 0; real_karts < num_karts; real_karts++)
|
||||
@@ -208,7 +222,6 @@ void ReplayRecorder::Save()
|
||||
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
||||
fprintf(fd, "track: %s\n", world->getTrack()->getIdent().c_str());
|
||||
fprintf(fd, "laps: %d\n", race_manager->getNumLaps());
|
||||
fprintf(fd, "reverse: %d\n", (int)race_manager->getReverseTrack());
|
||||
|
||||
unsigned int max_frames = (unsigned int)( stk_config->m_replay_max_time
|
||||
/ stk_config->m_replay_dt );
|
||||
@@ -245,5 +258,4 @@ void ReplayRecorder::Save()
|
||||
} // for i
|
||||
}
|
||||
fclose(fd);
|
||||
} // Save
|
||||
|
||||
} // save
|
||||
|
||||
@@ -49,6 +49,10 @@ private:
|
||||
/** Static pointer to the one instance of the replay object. */
|
||||
static ReplayRecorder *m_replay_recorder;
|
||||
|
||||
bool m_complete_replay;
|
||||
|
||||
bool m_incorrect_replay;
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Counts overall number of events stored. */
|
||||
unsigned int m_count;
|
||||
@@ -66,8 +70,7 @@ private:
|
||||
public:
|
||||
void init();
|
||||
void update(float dt);
|
||||
void reset();
|
||||
void Save();
|
||||
void save();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Creates a new instance of the replay object. */
|
||||
|
||||
@@ -68,7 +68,9 @@ void TrackInfoScreen::loadedFromFile()
|
||||
m_lap_spinner = getWidget<SpinnerWidget>("lap-spinner");
|
||||
m_ai_kart_spinner = getWidget<SpinnerWidget>("ai-spinner");
|
||||
m_reverse = getWidget<CheckBoxWidget>("reverse");
|
||||
m_record_race = getWidget<CheckBoxWidget>("record");
|
||||
m_reverse->setState(false);
|
||||
m_record_race->setState(false);
|
||||
|
||||
m_highscore_label = getWidget<LabelWidget>("highscores");
|
||||
|
||||
@@ -209,6 +211,14 @@ void TrackInfoScreen::init()
|
||||
else
|
||||
m_reverse->setState(false);
|
||||
|
||||
// Record race or not
|
||||
// -------------
|
||||
const bool record_available = race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL;
|
||||
m_record_race->setVisible(record_available);
|
||||
getWidget<LabelWidget>("record-race-text")->setVisible(record_available);
|
||||
if (record_available)
|
||||
m_record_race->setState(false);
|
||||
|
||||
// ---- High Scores
|
||||
m_highscore_label->setVisible(has_highscores);
|
||||
|
||||
@@ -358,6 +368,23 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
// checkbox.
|
||||
updateHighScores();
|
||||
}
|
||||
else if (name == "record")
|
||||
{
|
||||
const bool record = m_record_race->getState();
|
||||
race_manager->setRecordRace(record);
|
||||
m_ai_kart_spinner->setValue(0);
|
||||
// Disable AI when recording ghost race
|
||||
if (record)
|
||||
{
|
||||
m_ai_kart_spinner->setActive(false);
|
||||
race_manager->setNumKarts(race_manager->getNumLocalPlayers());
|
||||
UserConfigParams::m_num_karts = race_manager->getNumLocalPlayers();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ai_kart_spinner->setActive(true);
|
||||
}
|
||||
}
|
||||
else if (name == "lap-spinner")
|
||||
{
|
||||
assert(race_manager->modeHasLaps());
|
||||
|
||||
@@ -55,6 +55,9 @@ class TrackInfoScreen : public GUIEngine::Screen,
|
||||
/** Check box for reverse mode. */
|
||||
GUIEngine::CheckBoxWidget* m_reverse;
|
||||
|
||||
/** Check box for record race. */
|
||||
GUIEngine::CheckBoxWidget* m_record_race;
|
||||
|
||||
/** The label of the highscore list. */
|
||||
GUIEngine::LabelWidget* m_highscore_label;
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ bool handleContextMenuAction(s32 cmdID)
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_REPLAY)
|
||||
{
|
||||
ReplayRecorder::get()->Save();
|
||||
ReplayRecorder::get()->save();
|
||||
}
|
||||
else if (cmdID == DEBUG_SAVE_HISTORY)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user