From 49d7a2fbbc1d95a5b05fb113fffec2fa55a28bab Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 13 Jul 2018 23:34:50 +0800 Subject: [PATCH] Use count up ticks on rewinding for time limit in soccer game --- src/input/input_manager.cpp | 4 ++-- src/items/attachment.cpp | 2 +- src/items/network_item_manager.cpp | 12 ++++++------ src/items/powerup.cpp | 4 ++-- src/items/powerup_manager.cpp | 2 +- src/karts/abstract_kart_animation.cpp | 2 +- src/karts/kart.cpp | 4 ++-- src/main_loop.cpp | 2 +- src/modes/world_status.cpp | 17 +++++++++++++++++ src/modes/world_status.hpp | 2 +- src/network/protocols/game_protocol.cpp | 10 +++++----- src/network/race_event_manager.cpp | 3 ++- src/network/rewind_manager.cpp | 12 ++++++------ src/network/rewind_queue.cpp | 4 ++-- src/race/history.cpp | 6 +++--- 15 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index fa5dba7b9..1f956a2e3 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -302,9 +302,9 @@ void InputManager::handleStaticAction(int key, int value) fgets(s, 256, stdin); int t; StringUtils::fromString(s,t); - RewindManager::get()->rewindTo(t, world->getTimeTicks()); + RewindManager::get()->rewindTo(t, world->getTicksSinceStart()); Log::info("Rewind", "Rewinding from %d to %d", - world->getTimeTicks(), t); + world->getTicksSinceStart(), t); } break; diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index fd860bd5a..e48033bda 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -345,7 +345,7 @@ void Attachment::hitBanana(ItemState *item_state) // Use this as a basic random number to make sync with server easier. // Divide by 16 to increase probablity to have same time as server in // case of a few physics frames different between client and server. - int ticks = World::getWorld()->getTimeTicks() / 16; + int ticks = World::getWorld()->getTicksSinceStart() / 16; switch(getType()) // If there already is an attachment, make it worse :) { case ATTACH_BOMB: diff --git a/src/items/network_item_manager.cpp b/src/items/network_item_manager.cpp index b09c20d38..70a218050 100644 --- a/src/items/network_item_manager.cpp +++ b/src/items/network_item_manager.cpp @@ -101,7 +101,7 @@ void NetworkItemManager::collectedItem(Item *item, AbstractKart *kart) { // The server saves the collected item as item event info m_item_events.lock(); - m_item_events.getData().emplace_back(World::getWorld()->getTimeTicks(), + m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(), item->getItemId(), kart->getWorldKartId()); m_item_events.unlock(); @@ -136,7 +136,7 @@ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type, // Server: store the data for this event: m_item_events.lock(); - m_item_events.getData().emplace_back(World::getWorld()->getTimeTicks(), + m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(), type, item->getItemId(), kart->getWorldKartId(), kart->getXYZ()); @@ -246,7 +246,7 @@ void NetworkItemManager::forwardTime(int ticks) void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) { assert(NetworkConfig::get()->isClient()); - // The state at World::getTimeTicks() needs to be restored. The confirmed + // The state at World::getTicksSinceStart() needs to be restored. The confirmed // state in this instance was taken at m_confirmed_state_time. First // forward this confirmed state to the current time (i.e. world time). // This is done in several steps: @@ -332,10 +332,10 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) // Inform the server which events have been received. if (auto gp = GameProtocol::lock()) - gp->sendItemEventConfirmation(World::getWorld()->getTimeTicks()); + gp->sendItemEventConfirmation(World::getWorld()->getTicksSinceStart()); // Forward the confirmed item state till the world time: - int dt = World::getWorld()->getTimeTicks() - current_time; + int dt = World::getWorld()->getTicksSinceStart() - current_time; if(dt>0) forwardTime(dt); // Restore the state to the current world time: @@ -363,6 +363,6 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count) } // Now we save the current local - m_confirmed_state_time = World::getWorld()->getTimeTicks(); + m_confirmed_state_time = World::getWorld()->getTicksSinceStart(); } // restoreState diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 722ee259f..fc3f0895c 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -504,7 +504,7 @@ void Powerup::hitBonusBox(const ItemState &item_state) // number to spread the random values across the (typically 200) // weights used in the PowerupManager - same for the position. int random_number = item_state.getItemId()*31 - + world->getTimeTicks() / 10 + position*23; + + world->getTicksSinceStart() / 10 + position*23; new_powerup = powerup_manager->getRandomPowerup(position, &n, random_number); if (new_powerup != PowerupManager::POWERUP_RUBBERBALL || @@ -514,7 +514,7 @@ void Powerup::hitBonusBox(const ItemState &item_state) } if(new_powerup == PowerupManager::POWERUP_RUBBERBALL) - powerup_manager->setBallCollectTicks(world->getTimeTicks()); + powerup_manager->setBallCollectTicks(world->getTicksSinceStart()); // Always add a new powerup in ITEM_MODE_NEW (or if the kart // doesn't have a powerup atm). diff --git a/src/items/powerup_manager.cpp b/src/items/powerup_manager.cpp index c2303a6e7..d2f1d3b53 100644 --- a/src/items/powerup_manager.cpp +++ b/src/items/powerup_manager.cpp @@ -416,7 +416,7 @@ int PowerupManager::WeightsData::getRandomItem(int rank, int random_number) // We don't do more, because it would need to be decoded from enum later #ifdef ITEM_DISTRIBUTION_DEBUG Log::verbose("Powerup", "World %d rank %d random %d %d item %d", - World::getWorld()->getTimeTicks(), rank, random_number, + World::getWorld()->getTicksSinceStart(), rank, random_number, original_random_number, powerup); #endif diff --git a/src/karts/abstract_kart_animation.cpp b/src/karts/abstract_kart_animation.cpp index 900714f65..3b069ad81 100644 --- a/src/karts/abstract_kart_animation.cpp +++ b/src/karts/abstract_kart_animation.cpp @@ -97,7 +97,7 @@ AbstractKartAnimation::~AbstractKartAnimation() btTransform m_transform; public: AnimationEvent(AbstractKart* kart) - : RewindInfo(World::getWorld()->getTimeTicks(), + : RewindInfo(World::getWorld()->getTicksSinceStart(), true/*is_confirmed*/) { m_kart = kart; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 3ee96f268..97bb92b34 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1492,7 +1492,7 @@ void Kart::update(int ticks) "maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f " "noderot(45) %f suslen %f", getIdent().c_str(), - World::getWorld()->getTime(), World::getWorld()->getTimeTicks(), + World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(), getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(), m_body->getWorldTransform().getOrigin().getX(), m_body->getWorldTransform().getOrigin().getY(), @@ -1604,7 +1604,7 @@ void Kart::update(int ticks) if(UserConfigParams::m_material_debug) { Log::info("Kart","World %d %s\tfraction %f\ttime %d.", - World::getWorld()->getTimeTicks(), + World::getWorld()->getTicksSinceStart(), material->getTexFname().c_str(), material->getMaxSpeedFraction(), material->getSlowDownTicks() ); diff --git a/src/main_loop.cpp b/src/main_loop.cpp index a9c8ca4a2..2963f6766 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -374,7 +374,7 @@ void MainLoop::run() GUIEngine::update(frame_duration); PROFILER_POP_CPU_MARKER(); if (World::getWorld() && history->replayHistory()) - history->updateReplay(World::getWorld()->getTimeTicks()); + history->updateReplay(World::getWorld()->getTicksSinceStart()); PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00); SFXManager::get()->update(); PROFILER_POP_CPU_MARKER(); diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index a8f1697c6..046d8c4f0 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -499,6 +499,23 @@ void WorldStatus::setTicks(int ticks) m_time = stk_config->ticks2Time(ticks); } // setTicks +//----------------------------------------------------------------------------- +/** Sets a new time for the world time (used by rewind), measured in ticks. + * \param ticks New time in ticks to set (always count upwards). + */ +void WorldStatus::setTicksForRewind(int ticks) +{ + m_count_up_ticks = ticks; + if (race_manager->hasTimeTarget()) + { + m_time_ticks = stk_config->time2Ticks(race_manager->getTimeTarget()) - + m_count_up_ticks; + } + else + m_time_ticks = ticks; + m_time = stk_config->ticks2Time(m_time_ticks); +} // setTicksForRewind + //----------------------------------------------------------------------------- /** Pauses the game and switches to the specified phase. * \param phase Phase to switch to. diff --git a/src/modes/world_status.hpp b/src/modes/world_status.hpp index dc905904c..66afdacda 100644 --- a/src/modes/world_status.hpp +++ b/src/modes/world_status.hpp @@ -154,7 +154,7 @@ public: virtual void terminateRace(); void setTime(const float time); void setTicks(int ticks); - + void setTicksForRewind(int ticks); // ------------------------------------------------------------------------ // Note: GO_PHASE is both: start phase and race phase bool isStartPhase() const { return m_phasegetTimeTicks(); + a.m_ticks = World::getWorld()->getTicksSinceStart(); m_all_actions.push_back(a); @@ -147,7 +147,7 @@ void GameProtocol::controllerAction(int kart_id, PlayerAction action, .addUInt32(val_l).addUInt32(val_r); RewindManager::get()->addEvent(this, s, /*confirmed*/true, - World::getWorld()->getTimeTicks() ); + World::getWorld()->getTicksSinceStart()); } // controllerAction // ---------------------------------------------------------------------------- @@ -214,7 +214,7 @@ void GameProtocol::handleControllerAction(Event *event) rewind_delta += max_adjustment; Log::info("GameProtocol", "At %d %f %d requesting time adjust" " (speed up) of %d for host %d", - World::getWorld()->getTimeTicks(), StkTime::getRealTime(), + World::getWorld()->getTicksSinceStart(), StkTime::getRealTime(), not_rewound, rewind_delta, event->getPeer()->getHostId()); // This message from a client triggered a rewind in the server. // To avoid this, signal to the client that it should speed up. @@ -228,7 +228,7 @@ void GameProtocol::handleControllerAction(Event *event) const int adjustment = ticks_difference - cur_diff; Log::info("GameProtocol", "At %d %f %d requesting time adjust" " (slow down) of %d for host %d", - World::getWorld()->getTimeTicks(), StkTime::getRealTime(), + World::getWorld()->getTicksSinceStart(), StkTime::getRealTime(), not_rewound, adjustment, event->getPeer()->getHostId()); adjustTimeForClient(event->getPeer(), adjustment); }*/ @@ -310,7 +310,7 @@ void GameProtocol::startNewState() assert(NetworkConfig::get()->isServer()); m_data_to_send->clear(); m_data_to_send->addUInt8(GP_STATE) - .addUInt32(World::getWorld()->getTimeTicks()); + .addUInt32(World::getWorld()->getTicksSinceStart()); } // startNewState // ---------------------------------------------------------------------------- diff --git a/src/network/race_event_manager.cpp b/src/network/race_event_manager.cpp index 13be70154..7e3140611 100644 --- a/src/network/race_event_manager.cpp +++ b/src/network/race_event_manager.cpp @@ -29,7 +29,7 @@ void RaceEventManager::update(int ticks) // This might adjust dt - if a new state is being played, the dt is // determined from the last state till 'now' PROFILER_PUSH_CPU_MARKER("RaceEvent:play event", 100, 100, 100); - RewindManager::get()->playEventsTill(World::getWorld()->getTimeTicks(), + RewindManager::get()->playEventsTill(World::getWorld()->getTicksSinceStart(), &ticks); PROFILER_POP_CPU_MARKER(); World::getWorld()->updateWorld(ticks); @@ -41,6 +41,7 @@ bool RaceEventManager::isRaceOver() if(!World::getWorld()) return false; return (World::getWorld()->getPhase() > WorldStatus::RACE_PHASE && + World::getWorld()->getPhase() != WorldStatus::GOAL_PHASE && World::getWorld()->getPhase() != WorldStatus::IN_GAME_MENU_PHASE); } // isRaceOver diff --git a/src/network/rewind_manager.cpp b/src/network/rewind_manager.cpp index dab801a33..fcf2b7163 100644 --- a/src/network/rewind_manager.cpp +++ b/src/network/rewind_manager.cpp @@ -116,7 +116,7 @@ void RewindManager::addEvent(EventRewinder *event_rewinder, } if (ticks < 0) - ticks = World::getWorld()->getTimeTicks(); + ticks = World::getWorld()->getTicksSinceStart(); m_rewind_queue.addLocalEvent(event_rewinder, buffer, confirmed, ticks); } // addEvent @@ -190,7 +190,7 @@ void RewindManager::update(int ticks_not_used) m_all_rewinder.size() == 0 || m_is_rewinding) return; - int ticks = World::getWorld()->getTimeTicks(); + int ticks = World::getWorld()->getTicksSinceStart(); m_not_rewound_ticks.store(ticks, std::memory_order_relaxed); @@ -237,7 +237,7 @@ void RewindManager::playEventsTill(int world_ticks, int *ticks) PROFILER_PUSH_CPU_MARKER("Rewind", 128, 128, 128); rewindTo(rewind_ticks, world_ticks); // This should replay everything up to 'now' - assert(World::getWorld()->getTimeTicks() == world_ticks); + assert(World::getWorld()->getTicksSinceStart() == world_ticks); PROFILER_POP_CPU_MARKER(); Log::setPrefix(""); } @@ -292,7 +292,7 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks) // world time is set first, since e.g. the NetworkItem manager relies // on having the access to the 'confirmed' state time using // the world timer. - world->setTicks(exact_rewind_ticks); + world->setTicksForRewind(exact_rewind_ticks); // Get the (first) full state to which we have to rewind RewindInfo *current = m_rewind_queue.getCurrent(); @@ -332,9 +332,9 @@ void RewindManager::rewindTo(int rewind_ticks, int now_ticks) } // Now go forward through the list of rewind infos till we reach 'now': - while (world->getTimeTicks() < now_ticks) + while (world->getTicksSinceStart() < now_ticks) { - m_rewind_queue.replayAllEvents(world->getTimeTicks()); + m_rewind_queue.replayAllEvents(world->getTicksSinceStart()); // Now simulate the next time step world->updateWorld(1); diff --git a/src/network/rewind_queue.cpp b/src/network/rewind_queue.cpp index 411860855..ab14482d6 100644 --- a/src/network/rewind_queue.cpp +++ b/src/network/rewind_queue.cpp @@ -303,7 +303,7 @@ void RewindQueue::mergeNetworkData(int world_ticks, bool *needs_rewind, { Log::verbose("rewindqueue", "world %d rewindticks %d latest_confirmed %d", - World::getWorld()->getTimeTicks(), *rewind_ticks, + World::getWorld()->getTicksSinceStart(), *rewind_ticks, m_latest_confirmed_state_time); *rewind_ticks = m_latest_confirmed_state_time; *needs_rewind = m_latest_confirmed_state_time < world_ticks; @@ -365,7 +365,7 @@ int RewindQueue::undoUntil(int undo_ticks) // This shouldn't happen, but add some debug info just in case Log::error("undoUntil", "At %d rewinding to %d current = %d = begin", - World::getWorld()->getTimeTicks(), undo_ticks, + World::getWorld()->getTicksSinceStart(), undo_ticks, (*m_current)->getTicks()); } m_current--; diff --git a/src/race/history.cpp b/src/race/history.cpp index bb2a5c7e4..c7dcbced4 100644 --- a/src/race/history.cpp +++ b/src/race/history.cpp @@ -80,7 +80,7 @@ void History::addEvent(int kart_id, PlayerAction pa, int value) InputEvent ie; // The event is added before m_current is increased. So in order to // save the right index for this event, we need to use m_current+1. - ie.m_world_ticks = World::getWorld()->getTimeTicks(); + ie.m_world_ticks = World::getWorld()->getTicksSinceStart(); ie.m_action = pa; ie.m_value = value; ie.m_kart_index = kart_id; @@ -102,7 +102,7 @@ void History::updateReplay(int world_ticks) const InputEvent &ie = m_all_input_events[m_event_index]; AbstractKart *kart = world->getKart(ie.m_kart_index); Log::verbose("history", "time %d event-time %d action %d %d", - world->getTimeTicks(), ie.m_world_ticks, ie.m_action, + world->getTicksSinceStart(), ie.m_world_ticks, ie.m_action, ie.m_value); kart->getController()->action(ie.m_action, ie.m_value); m_event_index++; @@ -168,7 +168,7 @@ void History::Save() { fprintf(fd, "model %d: %s\n",k, world->getKart(k)->getIdent().c_str()); } - fprintf(fd, "count: %d\n", m_all_input_events.size()); + fprintf(fd, "count: %zu\n", m_all_input_events.size()); for (unsigned int i = 0; i < m_all_input_events.size(); i++) {