Merge remote-tracking branch 'origin/master'

This commit is contained in:
Benau 2018-04-23 23:47:30 +08:00
commit b919c82da5
26 changed files with 1046 additions and 666 deletions

View File

@ -41,7 +41,7 @@
#include "utils/vs.hpp"
#include "ISceneManager.h"
#include <algorithm>
#include <cmath>
std::vector<Camera*> Camera::m_all_cameras;
@ -58,6 +58,11 @@ Camera* Camera::createCamera(AbstractKart* kart, const int index)
Camera *camera = createCamera(index, m_default_type, kart);
m_all_cameras.push_back(camera);
std::sort(m_all_cameras.begin(), m_all_cameras.end(),
[](const Camera* a, const Camera* b)
{
return a->getIndex() < b->getIndex();
});
return camera;
} // createCamera(kart)

View File

@ -606,9 +606,8 @@ void Attachment::update(int ticks)
}
case ATTACH_BUBBLEGUM_SHIELD:
case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
if (m_ticks_left < 0)
if (m_ticks_left <= 0)
{
m_ticks_left = 0;
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
m_bubble_explode_sound =
SFXManager::get()->createSoundSource("bubblegum_explode");

View File

@ -555,9 +555,6 @@ void ArenaAI::useItems(const float dt)
case PowerupManager::POWERUP_PARACHUTE:
break; // POWERUP_PARACHUTE
case PowerupManager::POWERUP_ANVIL:
break; // POWERUP_ANVIL
case PowerupManager::POWERUP_RUBBERBALL:
break;

File diff suppressed because it is too large Load Diff

View File

@ -194,6 +194,9 @@ private:
enum {SKID_PROBAB_NOT_YET, SKID_PROBAB_NO_SKID, SKID_PROBAB_SKID}
m_skid_probability_state;
/** This is used by computeSkill to know what skill is used */
enum SkillType {ITEM_SKILL, NITRO_SKILL};
/** The last item selected for collection, for which a probability
* was determined. */
const Item *m_last_item_random;
@ -242,11 +245,19 @@ private:
void handleRaceStart();
void handleAcceleration(int ticks);
void handleSteering(float dt);
int computeSkill(SkillType type);
void handleItems(const float dt, const Vec3 *aim_point,
int last_node);
int last_node, int item_skill);
void handleBubblegum(int item_skill, const std::vector<const Item *> &items_to_collect,
const std::vector<const Item *> &items_to_avoid);
void handleCake(int item_skill);
void handleBowling(int item_skill);
void handleSwatter(int item_skill);
void handleSwitch(int item_skill, const std::vector<const Item *> &items_to_collect,
const std::vector<const Item *> &items_to_avoid);
void handleRescue(const float dt);
void handleBraking();
void handleNitroAndZipper();
void handleNitroAndZipper(int item_skill);
void computeNearestKarts();
void handleItemCollectionAndAvoidance(Vec3 *aim_point,
int last_node);

View File

@ -2265,7 +2265,7 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
void Kart::playCrashSFX(const Material* m, AbstractKart *k)
{
int ticks_since_start = World::getWorld()->getTicksSinceStart();
if(ticks_since_start-m_ticks_last_crash < 0.5f) return;
if(ticks_since_start-m_ticks_last_crash < 60) return;
m_ticks_last_crash = ticks_since_start;
// After a collision disable the engine for a short time so that karts
@ -2724,7 +2724,8 @@ void Kart::updateFlying()
*/
void Kart::loadData(RaceManager::KartType type, bool is_animated_model)
{
bool always_animated = (type == RaceManager::KT_PLAYER && race_manager->getNumPlayers() == 1);
bool always_animated = (type == RaceManager::KT_PLAYER &&
race_manager->getNumLocalPlayers() == 1);
m_node = m_kart_model->attachModel(is_animated_model, always_animated);
#ifdef DEBUG

View File

@ -199,11 +199,11 @@ void MaxSpeed::SpeedIncrease::rewindTo(BareNetworkString *buffer,
* value is changed to something else).
*/
void MaxSpeed::setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time, int duration)
int fade_in_ticks, int duration)
{
assert(category>=MS_DECREASE_MIN && category <MS_DECREASE_MAX);
m_speed_decrease[category].m_max_speed_fraction = max_speed_fraction;
m_speed_decrease[category].m_fade_in_time = fade_in_time;
m_speed_decrease[category].m_fade_in_ticks = fade_in_ticks;
m_speed_decrease[category].m_duration = duration;
} // setSlowdown
@ -227,11 +227,11 @@ void MaxSpeed::SpeedDecrease::update(int ticks)
}
float diff = m_current_fraction - m_max_speed_fraction;
if(diff > 0)
if (diff > 0)
{
float dt = stk_config->ticks2Time(ticks);
if (diff * m_fade_in_time > ticks)
m_current_fraction -= float(dt)/m_fade_in_time;
if (diff * m_fade_in_ticks > ticks)
m_current_fraction -= float(ticks) / float(m_fade_in_ticks);
else
m_current_fraction = m_max_speed_fraction;
}
@ -247,7 +247,7 @@ void MaxSpeed::SpeedDecrease::update(int ticks)
void MaxSpeed::SpeedDecrease::saveState(BareNetworkString *buffer) const
{
buffer->addFloat(m_max_speed_fraction);
buffer->addUInt32(m_fade_in_time);
buffer->addUInt32(m_fade_in_ticks);
buffer->addFloat(m_current_fraction);
buffer->addUInt32(m_duration);
} // saveState
@ -261,7 +261,7 @@ void MaxSpeed::SpeedDecrease::rewindTo(BareNetworkString *buffer,
if(is_active)
{
m_max_speed_fraction = buffer->getFloat();
m_fade_in_time = buffer->getUInt32();
m_fade_in_ticks = buffer->getUInt32();
m_current_fraction = buffer->getFloat();
m_duration = buffer->getUInt32();
}

View File

@ -127,7 +127,7 @@ private:
/** The maximum slowdown to apply. */
float m_max_speed_fraction;
/** How long it should take for the full slowdown to take effect. */
int m_fade_in_time;
int m_fade_in_ticks;
/** The current slowdown fraction, taking the fade-in time
* into account. */
float m_current_fraction;
@ -148,7 +148,7 @@ private:
{
m_max_speed_fraction = 1.0f;
m_current_fraction = 1.0f;
m_fade_in_time = 0;
m_fade_in_ticks = 0;
m_duration = 0;
} //reset
// --------------------------------------------------------------------

View File

@ -363,6 +363,7 @@ void MainLoop::run()
GUIEngine::ModalDialog::dismiss();
if (World::getWorld())
{
race_manager->clearNetworkGrandPrixResult();
race_manager->exitRace();
}
if (!ProfileWorld::isNoGraphics())

View File

@ -234,9 +234,8 @@ void CutsceneWorld::update(int ticks)
double prev_time = m_time;
double now = StkTime::getRealTime();
m_time = now - m_time_at_second_reset;
ticks = stk_config->time2Ticks(float(m_time - prev_time));
}
float fade = 0.0f;
float fadeIn = -1.0f;
float fadeOut = -1.0f;

View File

@ -27,6 +27,7 @@
#include "karts/controller/controller.hpp"
#include "karts/kart_properties.hpp"
#include "graphics/material.hpp"
#include "guiengine/modaldialog.hpp"
#include "physics/physics.hpp"
#include "race/history.hpp"
#include "states_screens/race_gui_base.hpp"
@ -245,16 +246,19 @@ void LinearWorld::updateGraphics(float dt)
m_last_lap_sfx_playing = false;
}
const unsigned int kart_amount = getNumKarts();
for (unsigned int i = 0; i<kart_amount; i++)
if (!GUIEngine::ModalDialog::isADialogActive())
{
// ---------- update rank ------
if (!m_karts[i]->hasFinishedRace() &&
!m_karts[i]->isEliminated())
const unsigned int kart_amount = getNumKarts();
for (unsigned int i = 0; i<kart_amount; i++)
{
checkForWrongDirection(i, dt);
}
} // for i <kart_amount
// ---------- update rank ------
if (!m_karts[i]->hasFinishedRace() &&
!m_karts[i]->isEliminated())
{
checkForWrongDirection(i, dt);
}
} // for i <kart_amount
}
} // updateGraphics

View File

@ -19,6 +19,7 @@
#include "network/game_setup.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp"
#include "network/network_config.hpp"
@ -28,6 +29,8 @@
#include "race/race_manager.hpp"
#include "utils/log.hpp"
#include <algorithm>
//-----------------------------------------------------------------------------
/** Update and see if any player disconnects.
* \param remove_disconnected_players remove the disconnected players,
@ -75,7 +78,8 @@ void GameSetup::loadWorld()
{
assert(!m_tracks.empty());
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
if (PlayerManager::getCurrentPlayer())
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->setTimeTarget(0.0f);
race_manager->setReverseTrack(m_reverse);
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
@ -112,7 +116,10 @@ void GameSetup::addServerInfo(NetworkString* ns)
{
if (isGrandPrix())
{
ns->addUInt8((uint8_t)2).addUInt8((uint8_t)m_tracks.size())
uint8_t cur_track = (uint8_t)m_tracks.size();
if (!isGrandPrixStarted())
cur_track = 0;
ns->addUInt8((uint8_t)2).addUInt8(cur_track)
.addUInt8(getExtraServerInfo());
}
else
@ -128,3 +135,28 @@ void GameSetup::addServerInfo(NetworkString* ns)
}
ns->encodeString(NetworkConfig::get()->getMOTD());
} // addServerInfo
//-----------------------------------------------------------------------------
void GameSetup::sortPlayersForGrandPrix()
{
if (!isGrandPrix() || m_tracks.size() == 1)
return;
std::lock_guard<std::mutex> lock(m_players_mutex);
std::sort(m_players.begin(), m_players.end(),
[](const std::weak_ptr<NetworkPlayerProfile>& a,
const std::weak_ptr<NetworkPlayerProfile>& b)
{
// They should never expired
auto c = a.lock();
assert(c);
auto d = b.lock();
assert(d);
return (c->getScore() < d->getScore()) ||
(c->getScore() == d->getScore() &&
c->getOverallTime() > d->getOverallTime());
});
if (UserConfigParams::m_gp_most_points_first)
{
std::reverse(m_players.begin(), m_players.end());
}
} // sortPlayersForGrandPrix

View File

@ -46,9 +46,6 @@ private:
/** Information about all connected players. */
std::vector<std::weak_ptr<NetworkPlayerProfile> > m_players;
/** Stores the number of local players. */
int m_num_local_players;
std::vector<std::string> m_tracks;
unsigned m_laps;
@ -61,7 +58,6 @@ public:
// ------------------------------------------------------------------------
GameSetup()
{
m_num_local_players = 0;
m_extra_server_info = -1;
reset();
}
@ -73,12 +69,6 @@ public:
// ------------------------------------------------------------------------
void update(bool remove_disconnected_players);
// ------------------------------------------------------------------------
/** Sets the number of local players. */
void setNumLocalPlayers(int n) { m_num_local_players = n; }
// ------------------------------------------------------------------------
/** Returns the nunber of local players. */
int getNumLocalPlayers() const { return m_num_local_players; }
// ------------------------------------------------------------------------
/** \brief Get the players that are / were in the game
* \return A vector containing pointers on the players profiles. */
const std::vector<std::weak_ptr<NetworkPlayerProfile> >& getPlayers() const
@ -118,7 +108,8 @@ public:
// ------------------------------------------------------------------------
void reset()
{
m_tracks.clear();
if (!isGrandPrixStarted())
m_tracks.clear();
m_laps = 0;
m_reverse = false;
}
@ -153,7 +144,17 @@ public:
return m_extra_server_info != 0;
}
// ------------------------------------------------------------------------
bool isGrandPrixStarted() const
{
return isGrandPrix() && !m_tracks.empty() &&
m_tracks.size() != getTotalGrandPrixTracks();
}
// ------------------------------------------------------------------------
void stopGrandPrix() { m_tracks.clear(); }
// ------------------------------------------------------------------------
const std::vector<std::string>& getAllTracks() const { return m_tracks; }
// ------------------------------------------------------------------------
void sortPlayersForGrandPrix();
};
#endif // GAME_SETUP_HPP

View File

@ -59,6 +59,12 @@ private:
/** The local player id relative to each peer. */
int m_local_player_id;
/** Score if grand prix. */
int m_score;
/** Overall time if grand prix. */
float m_overall_time;
public:
NetworkPlayerProfile(std::shared_ptr<STKPeer> peer,
const irr::core::stringw &name, uint32_t host_id,
@ -72,7 +78,8 @@ public:
m_default_kart_color = default_kart_color;
m_online_id = online_id;
m_per_player_difficulty = per_player_difficulty;
m_local_player_id = local_player_id;
m_local_player_id = local_player_id;
resetGrandPrixData();
}
// ------------------------------------------------------------------------
~NetworkPlayerProfile() {}
@ -80,33 +87,45 @@ public:
bool isLocalPlayer() const;
// ------------------------------------------------------------------------
/** Returns the host id of this player. */
uint32_t getHostId() const { return m_host_id; }
uint32_t getHostId() const { return m_host_id; }
// ------------------------------------------------------------------------
/** Sets the kart name for this player. */
void setKartName(const std::string &kart_name) { m_kart_name = kart_name; }
// ------------------------------------------------------------------------
/** Returns the name of the kart this player has selected. */
const std::string &getKartName() const { return m_kart_name; }
const std::string &getKartName() const { return m_kart_name; }
// ------------------------------------------------------------------------
/** Retuens the local player id for this player. */
int getLocalPlayerId() const { return m_local_player_id; }
int getLocalPlayerId() const { return m_local_player_id; }
// ------------------------------------------------------------------------
/** Returns the per-player difficulty. */
PerPlayerDifficulty getPerPlayerDifficulty() const
{
return m_per_player_difficulty;
} // getPerPlayerDifficulty
{ return m_per_player_difficulty; }
// ------------------------------------------------------------------------
/** Returns the name of this player. */
const irr::core::stringw& getName() const { return m_player_name; }
const irr::core::stringw& getName() const { return m_player_name; }
// ------------------------------------------------------------------------
float getDefaultKartColor() const { return m_default_kart_color; }
float getDefaultKartColor() const { return m_default_kart_color; }
// ------------------------------------------------------------------------
uint32_t getOnlineId() const { return m_online_id; }
uint32_t getOnlineId() const { return m_online_id; }
// ------------------------------------------------------------------------
bool isOfflineAccount() const { return m_online_id == 0; }
bool isOfflineAccount() const { return m_online_id == 0; }
// ------------------------------------------------------------------------
std::shared_ptr<STKPeer> getPeer() const { return m_peer.lock(); }
std::shared_ptr<STKPeer> getPeer() const { return m_peer.lock(); }
// ------------------------------------------------------------------------
int getScore() const { return m_score; }
// ------------------------------------------------------------------------
float getOverallTime() const { return m_overall_time; }
// ------------------------------------------------------------------------
void setScore(int score) { m_score = score; }
// ------------------------------------------------------------------------
void setOverallTime(float time) { m_overall_time = time; }
// ------------------------------------------------------------------------
void resetGrandPrixData()
{
m_score = 0;
m_overall_time = 0.0f;
}
}; // class NetworkPlayerProfile

View File

@ -18,6 +18,7 @@
#include "network/protocols/client_lobby.hpp"
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "config/player_manager.hpp"
#include "guiengine/modaldialog.hpp"
@ -320,35 +321,7 @@ void ClientLobby::update(int ticks)
break;
case CONNECTED:
break;
case KART_SELECTION:
{
// In case the user opened a user info dialog
GUIEngine::ModalDialog::dismiss();
NetworkKartSelectionScreen* screen =
NetworkKartSelectionScreen::getInstance();
screen->setAvailableKartsFromServer(m_available_karts);
// In case of auto-connect, use random karts (or previous kart) from
// server and go to track selection (or grand prix later)
if (NetworkConfig::get()->isAutoConnect())
{
input_manager->setMasterPlayerOnly(true);
for (auto& p : NetworkConfig::get()->getNetworkPlayers())
{
StateManager::get()
->createActivePlayer(std::get<1>(p), std::get<0>(p));
}
input_manager->getDeviceManager()->setAssignMode(ASSIGN);
TracksScreen::getInstance()->setNetworkTracks();
TracksScreen::getInstance()->push();
}
else
{
screen->push();
}
m_state.store(SELECTING_KARTS);
}
break;
case SELECTING_KARTS:
case SELECTING_ASSETS:
break;
case PLAYING:
break;
@ -409,6 +382,7 @@ void ClientLobby::disconnectedPlayer(Event* event)
if (!checkDataSize(event, 1)) return;
NetworkString &data = event->data();
SFXManager::get()->quickSound("appear");
unsigned disconnected_player_count = data.getUInt8();
for (unsigned i = 0; i < disconnected_player_count; i++)
{
@ -439,8 +413,6 @@ void ClientLobby::connectionAccepted(Event* event)
STKHost::get()->setMyHostId(data.getUInt32());
assert(!NetworkConfig::get()->isAddingNetworkPlayers());
m_game_setup->setNumLocalPlayers((int)
NetworkConfig::get()->getNetworkPlayers().size());
// connection token
uint32_t token = data.getToken();
peer->setClientServerToken(token);
@ -481,8 +453,8 @@ void ClientLobby::handleServerInfo(Event* event)
NetworkConfig::get()->setServerMode(u_data);
auto game_mode = NetworkConfig::get()->getLocalGameMode();
race_manager->setMinorMode(game_mode.first);
// We may use single mode in network even it's grand prix
//race_manager->setMajorMode(game_mode.second);
// We use single mode in network even it's grand prix
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
//I18N: In the networking lobby
core::stringw mode_name = NetworkConfig::get()->getModeName(u_data);
@ -549,6 +521,7 @@ void ClientLobby::updatePlayerList(Event* event)
//-----------------------------------------------------------------------------
void ClientLobby::becomingServerOwner()
{
SFXManager::get()->quickSound("wee");
core::stringw msg = _("You are now the owner of server.");
MessageQueue::add(MessageQueue::MT_GENERIC, msg);
STKHost::get()->setAuthorisedToControl(true);
@ -567,6 +540,7 @@ void ClientLobby::handleChat(Event* event)
{
if (!UserConfigParams::m_lobby_chat)
return;
SFXManager::get()->quickSound("plopp");
std::string message;
event->data().decodeString(&message);
Log::info("ClientLobby", "%s", message.c_str());
@ -660,8 +634,8 @@ void ClientLobby::startingRaceNow()
*/
void ClientLobby::startSelection(Event* event)
{
m_state.store(KART_SELECTION);
const NetworkString& data = event->data();
uint8_t skip_kart_screen = data.getUInt8();
const unsigned kart_num = data.getUInt16();
const unsigned track_num = data.getUInt16();
m_available_karts.clear();
@ -678,7 +652,33 @@ void ClientLobby::startSelection(Event* event)
data.decodeString(&track);
m_available_tracks.insert(track);
}
Log::info("ClientLobby", "Kart selection starts now");
// In case the user opened a user info dialog
GUIEngine::ModalDialog::dismiss();
NetworkKartSelectionScreen* screen =
NetworkKartSelectionScreen::getInstance();
screen->setAvailableKartsFromServer(m_available_karts);
// In case of auto-connect or continue a grand prix, use random karts
// (or previous kart) from server and go to track selection
if (NetworkConfig::get()->isAutoConnect() || skip_kart_screen == 1)
{
input_manager->setMasterPlayerOnly(true);
for (auto& p : NetworkConfig::get()->getNetworkPlayers())
{
StateManager::get()
->createActivePlayer(std::get<1>(p), std::get<0>(p));
}
input_manager->getDeviceManager()->setAssignMode(ASSIGN);
TracksScreen::getInstance()->setNetworkTracks();
TracksScreen::getInstance()->push();
}
else
{
screen->push();
}
m_state.store(SELECTING_ASSETS);
Log::info("ClientLobby", "Selection starts now");
} // startSelection
//-----------------------------------------------------------------------------
@ -699,7 +699,9 @@ void ClientLobby::raceFinished(Event* event)
Log::info("ClientLobby", "Server notified that the race is finished.");
if (m_game_setup->isGrandPrix())
{
// fastest lap, and than each kart before / after grand prix points
int t = data.getUInt32();
static_cast<LinearWorld*>(World::getWorld())->setFastestLapTicks(t);
race_manager->configGrandPrixResultFromNetwork(data);
}
else if (race_manager->modeHasLaps())
{

View File

@ -35,8 +35,7 @@ private:
LINKED,
REQUESTING_CONNECTION,
CONNECTED, // means in the lobby room
KART_SELECTION, // Start kart selection, then go to next state
SELECTING_KARTS, // in the network kart selection screen
SELECTING_ASSETS, // in the kart selection or tracks screen
PLAYING, // racing
RACE_FINISHED, // race result shown
DONE,

View File

@ -23,6 +23,7 @@
#include "input/device_manager.hpp"
#include "modes/world.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
@ -90,7 +91,7 @@ void LobbyProtocol::configRemoteKart(
// Set number of global and local players.
race_manager->setNumPlayers((int)players.size(),
m_game_setup->getNumLocalPlayers());
(int)NetworkConfig::get()->getNetworkPlayers().size());
// Create the kart information for the race manager:
// -------------------------------------------------

View File

@ -97,7 +97,7 @@ ServerLobby::ServerLobby() : LobbyProtocol(NULL)
*/
ServerLobby::~ServerLobby()
{
if (m_server_registered && NetworkConfig::get()->isWAN())
if (m_server_registered)
{
unregisterServer();
}
@ -107,6 +107,13 @@ ServerLobby::~ServerLobby()
void ServerLobby::setup()
{
LobbyProtocol::setup();
if (m_game_setup->isGrandPrix() && !m_game_setup->isGrandPrixStarted())
{
auto players = m_game_setup->getConnectedPlayers();
for (auto player : players)
player->resetGrandPrixData();
}
StateManager::get()->resetActivePlayers();
// We use maximum 16bit unsigned limit
auto all_k = kart_properties_manager->getAllAvailableKarts();
@ -119,11 +126,10 @@ void ServerLobby::setup()
m_available_kts.second = { all_t.begin(), all_t.end() };
m_server_registered = false;
m_game_setup->setNumLocalPlayers(0); // no local players on a server
m_server_has_loaded_world.store(false);
// Initialise the data structures to detect if all clients and
// the server are ready:
m_server_has_loaded_world.store(false);
resetPeersReady();
m_peers_votes.clear();
m_server_delay = 0.0;
@ -266,6 +272,11 @@ void ServerLobby::asynchronousUpdate()
}
case REGISTER_SELF_ADDRESS:
{
if (m_game_setup->isGrandPrixStarted())
{
m_state = ACCEPTING_CLIENTS;
break;
}
// Register this server with the STK server. This will block
// this thread, but there is no need for the protocol manager
// to react to any requests before the server is registered.
@ -321,9 +332,11 @@ void ServerLobby::asynchronousUpdate()
case SELECTING:
if (m_timeout.load() < (float)StkTime::getRealTime())
{
std::lock_guard<std::mutex> lock(m_connection_mutex);
auto result = handleVote();
// Remove disconnected player (if any) one last time
m_game_setup->update(true);
m_game_setup->sortPlayersForGrandPrix();
auto players = m_game_setup->getConnectedPlayers();
NetworkString* load_world = getNetworkString();
load_world->setSynchronous(true);
@ -348,7 +361,6 @@ void ServerLobby::asynchronousUpdate()
}
load_world->encodeString(player->getKartName());
}
// TODO: sort players for grand prix here
configRemoteKart(players);
// Reset for next state usage
@ -372,7 +384,8 @@ void ServerLobby::asynchronousUpdate()
void ServerLobby::update(int ticks)
{
// Reset server to initial state if no more connected players
if (m_state.load() > ACCEPTING_CLIENTS &&
if ((m_state.load() > ACCEPTING_CLIENTS ||
m_game_setup->isGrandPrixStarted()) &&
STKHost::get()->getPeerCount() == 0 &&
NetworkConfig::get()->getServerIdFile().empty())
{
@ -382,6 +395,7 @@ void ServerLobby::update(int ticks)
stopCurrentRace();
}
std::lock_guard<std::mutex> lock(m_connection_mutex);
m_game_setup->stopGrandPrix();
m_state = NetworkConfig::get()->isLAN() ?
ACCEPTING_CLIENTS : REGISTER_SELF_ADDRESS;
setup();
@ -497,6 +511,7 @@ void ServerLobby::registerServer()
{
irr::core::stringc error(request->getInfo().c_str());
Log::error("ServerLobby", "%s", error.c_str());
m_server_registered = false;
m_state = ERROR_LEAVE;
}
delete request;
@ -577,18 +592,18 @@ void ServerLobby::startSelection(const Event *event)
return;
}
if (NetworkConfig::get()->isWAN())
if (m_server_registered)
{
assert(m_server_registered);
unregisterServer();
m_server_registered = false;
}
NetworkString *ns = getNetworkString(1);
// Start selection - must be synchronous since the receiver pushes
// a new screen, which must be donefrom the main thread.
// a new screen, which must be done from the main thread.
ns->setSynchronous(true);
ns->addUInt8(LE_START_SELECTION);
ns->addUInt8(LE_START_SELECTION).addUInt8(
m_game_setup->isGrandPrixStarted() ? 1 : 0);
// Remove karts / tracks from server that are not supported on all clients
std::set<std::string> karts_erase, tracks_erase;
@ -699,7 +714,36 @@ void ServerLobby::checkRaceFinished()
total->addUInt8(LE_RACE_FINISHED);
if (m_game_setup->isGrandPrix())
{
// fastest lap, and than each kart before / after grand prix points
// fastest lap
int fastest_lap =
static_cast<LinearWorld*>(World::getWorld())->getFastestLapTicks();
total->addUInt32(fastest_lap);
// all gp tracks
total->addUInt8((uint8_t)m_game_setup->getTotalGrandPrixTracks())
.addUInt8((uint8_t)m_game_setup->getAllTracks().size());
for (const std::string& gp_track : m_game_setup->getAllTracks())
total->encodeString(gp_track);
// each kart score and total time
auto& players = m_game_setup->getPlayers();
total->addUInt8((uint8_t)players.size());
for (unsigned i = 0; i < players.size(); i++)
{
int last_score = race_manager->getKartScore(i);
int cur_score = last_score;
float overall_time = race_manager->getOverallTime(i);
if (auto player = players[i].lock())
{
last_score = player->getScore();
cur_score += last_score;
overall_time = overall_time + player->getOverallTime();
player->setScore(cur_score);
player->setOverallTime(overall_time);
}
total->addUInt32(last_score).addUInt32(cur_score)
.addFloat(overall_time);
}
}
else if (race_manager->modeHasLaps())
{
@ -786,7 +830,8 @@ void ServerLobby::connectionRequested(Event* event)
const NetworkString &data = event->data();
// can we add the player ?
if (m_state != ACCEPTING_CLIENTS)
if (m_state != ACCEPTING_CLIENTS ||
m_game_setup->isGrandPrixStarted())
{
NetworkString *message = getNetworkString(2);
message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_BUSY);
@ -1054,7 +1099,7 @@ void ServerLobby::updateServerOwner()
void ServerLobby::kartSelectionRequested(Event* event)
{
std::lock_guard<std::mutex> lock(m_connection_mutex);
if (m_state != SELECTING)
if (m_state != SELECTING || m_game_setup->isGrandPrixStarted())
{
Log::warn("ServerLobby", "Received kart selection while in state %d.",
m_state.load());
@ -1284,3 +1329,10 @@ void ServerLobby::updateBanList()
m_ban_list[TransportAddress(ban.first).getIP()] = ban.second;
}
} // updateBanList
//-----------------------------------------------------------------------------
bool ServerLobby::waitingForPlayers() const
{
return m_state.load() == ACCEPTING_CLIENTS &&
!m_game_setup->isGrandPrixStarted();
} // waitingForPlayers

View File

@ -143,8 +143,7 @@ public:
void finishedLoadingWorld() OVERRIDE;
ServerState getCurrentState() const { return m_state.load(); }
void updateBanList();
virtual bool waitingForPlayers() const OVERRIDE
{ return m_state.load() == ACCEPTING_CLIENTS; }
virtual bool waitingForPlayers() const OVERRIDE;
virtual bool allPlayersReady() const OVERRIDE
{ return m_state.load() >= WAIT_FOR_RACE_STARTED; }

View File

@ -36,6 +36,12 @@ class Track;
*/
class GrandPrixData
{
protected:
/** The ident of the tracks in this grand prix in their right order, ident
* means the filename of the .track file without .track extension
* (ie. 'volcano'). */
std::vector<std::string> m_tracks;
public:
/** Used to classify GPs into groups */
enum GPGroupType
@ -57,11 +63,6 @@ private:
/** Original filename, only for error handling needed. */
std::string m_filename;
/** The ident of the tracks in this grand prix in their right order, ident
* means the filename of the .track file without .track extension
* (ie. 'volcano'). */
std::vector<std::string> m_tracks;
/** The number of laps that each track will be raced, in the right order */
std::vector<int> m_laps;
@ -105,7 +106,11 @@ public:
GrandPrixData(const std::string& filename, enum GPGroupType group);
/** Needed for simple creation of an instance of GrandPrixData */
GrandPrixData() {};
GrandPrixData() {}
virtual ~GrandPrixData() {}
virtual std::vector<std::string> getTrackNames(const bool includeLocked=false) const;
virtual unsigned int getNumberOfTracks(const bool includeLocked=false) const;
void changeTrackNumber(const unsigned int number_of_tracks,
const std::string& track_group);
@ -128,11 +133,9 @@ public:
bool writeToFile();
bool checkConsistency(bool log_error=true) const;
std::vector<std::string> getTrackNames(const bool includeLocked=false) const;
std::vector<int> getLaps(const bool includeLocked=false) const;
std::vector<bool> getReverse(const bool includeLocked=false) const;
bool isEditable() const;
unsigned int getNumberOfTracks(const bool includeLocked=false) const;
const std::string& getTrackId(const unsigned int track) const;
irr::core::stringw getTrackName(const unsigned int track) const;
unsigned int getLaps(const unsigned int track) const;

View File

@ -45,6 +45,7 @@
#include "modes/soccer_world.hpp"
#include "network/protocol_manager.hpp"
#include "network/network_config.hpp"
#include "network/network_string.hpp"
#include "network/protocols/lobby_protocol.hpp"
#include "network/race_event_manager.hpp"
#include "replay/replay_play.hpp"
@ -75,6 +76,7 @@ RaceManager::RaceManager()
m_coin_target = 0;
m_started_from_overworld = false;
m_have_kart_last_position_on_overworld = false;
m_num_local_players = 0;
setMaxGoal(0);
setTimeTarget(0.0f);
setReverseTrack(false);
@ -980,5 +982,70 @@ void RaceManager::startWatchingReplay(const std::string &track_ident,
} // startSingleRace
//-----------------------------------------------------------------------------
void RaceManager::configGrandPrixResultFromNetwork(NetworkString& ns)
{
setMajorMode(MAJOR_MODE_GRAND_PRIX);
class NetworkGrandPrixData : public GrandPrixData
{
public:
NetworkGrandPrixData() : GrandPrixData()
{ setGroup(GrandPrixData::GP_STANDARD); }
virtual std::vector<std::string>
getTrackNames(const bool includeLocked=false) const
{ return m_tracks; }
virtual unsigned int
getNumberOfTracks(const bool includeLocked=false) const
{ return m_tracks.size(); }
void addNetworkTrack(const std::string& t) { m_tracks.push_back(t); }
};
/* EOF */
NetworkGrandPrixData ngpd;
unsigned int track_size = ns.getUInt8();
unsigned int all_track_size = ns.getUInt8();
assert(all_track_size > 0);
m_track_number = all_track_size -1;
for (unsigned i = 0; i < all_track_size; i++)
{
std::string t;
ns.decodeString(&t);
ngpd.addNetworkTrack(t);
}
while (all_track_size < track_size)
{
ngpd.addNetworkTrack("");
all_track_size++;
}
m_tracks = ngpd.getTrackNames();
// For result screen we only need current lap and reserve
m_num_laps.resize(track_size, m_num_laps[0]);
m_reverse_track.resize(track_size, m_reverse_track[0]);
m_grand_prix = ngpd;
unsigned int player_size = ns.getUInt8();
assert(player_size == m_kart_status.size());
for (unsigned i = 0; i < player_size; i++)
{
int last_score = ns.getUInt32();
int cur_score = ns.getUInt32();
float overall_time = ns.getFloat();
m_kart_status[i].m_last_score = last_score;
m_kart_status[i].m_score = cur_score;
m_kart_status[i].m_overall_time = overall_time;
m_kart_status[i].m_gp_rank = i;
}
} // configGrandPrixResultFromNetwork
//-----------------------------------------------------------------------------
void RaceManager::clearNetworkGrandPrixResult()
{
if (m_major_mode != MAJOR_MODE_GRAND_PRIX)
return;
setMajorMode(MAJOR_MODE_SINGLE);
m_grand_prix = GrandPrixData();
m_track_number = 0;
m_tracks.clear();
m_num_laps.clear();
m_reverse_track.clear();
} // clearNetworkGrandPrixResult

View File

@ -36,6 +36,7 @@
#include "utils/vec3.hpp"
class AbstractKart;
class NetworkString;
class SavedGrandPrix;
class Track;
@ -303,7 +304,6 @@ private:
/** Stores remote kart information about all player karts. */
std::vector<RemoteKartInfo> m_player_karts;
std::vector<std::string> m_tracks;
std::vector<int> m_host_ids;
/** Number of local players. */
unsigned int m_num_local_players;
@ -786,6 +786,10 @@ public:
{
return m_num_spare_tire_karts;
} // getNumSpareTireKarts
// ------------------------------------------------------------------------
void configGrandPrixResultFromNetwork(NetworkString& ns);
// ------------------------------------------------------------------------
void clearNetworkGrandPrixResult();
}; // RaceManager

View File

@ -562,8 +562,9 @@ namespace Scripting
//-----------------------------------------------------------------------------
void ScriptEngine::update(double dt)
void ScriptEngine::update(int ticks)
{
double dt = stk_config->ticks2Time(ticks);
for (int i = m_pending_timeouts.size() - 1; i >= 0; i--)
{
PendingTimeout& curr = m_pending_timeouts[i];

View File

@ -82,7 +82,7 @@ namespace Scripting
void addPendingTimeout(double time, const std::string& callback_name);
void addPendingTimeout(double time, asIScriptFunction* delegate_fn);
void update(double dt);
void update(int ticks);
asIScriptEngine* getEngine() { return m_engine; }

View File

@ -772,9 +772,10 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
float distance = linear_world->getDistanceDownTrackForKart(kart_id, true)
+ Track::getCurrentTrack()->getTrackLength()*lap;
if ((position>1) &&
(previous_distance-distance<m_dist_show_overlap) &&
(!kart->hasFinishedRace()) )
(!kart->hasFinishedRace()) && lap >= 0 )
{
//linear translation : form (0,ICON_PLAYER_WIDTH+2) to
// (previous_x-x_base+(ICON_PLAYER_WIDTH+2)/2,0)

View File

@ -27,6 +27,7 @@
#include "graphics/2dutils.hpp"
#include "graphics/material.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/message_queue.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/widget.hpp"
@ -51,7 +52,7 @@
#include "scriptengine/property_animator.hpp"
#include "states_screens/feature_unlocked.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/network_kart_selection.hpp"
#include "states_screens/networking_lobby.hpp"
#include "states_screens/race_setup_screen.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
@ -89,7 +90,7 @@ void RaceResultGUI::init()
for (unsigned int kart_id = 0; kart_id < num_karts; kart_id++)
{
const AbstractKart *kart = World::getWorld()->getKart(kart_id);
if (kart->getController()->isPlayerController())
if (kart->getController()->isLocalPlayerController())
human_win = human_win && kart->getRaceResult();
}
@ -250,6 +251,33 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
displayScreenShots();
}
// If we're playing online :
if (World::getWorld()->isNetworkWorld())
{
if (name == "middle") // Continue button (return to server lobby)
{
// Signal to the server that this client is back in the lobby now.
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl)
cl->doneWithResults();
getWidget("middle")->setText(_("Waiting for others"));
}
if (name == "bottom") // Quit server (return to online lan / wan menu)
{
race_manager->clearNetworkGrandPrixResult();
if (STKHost::existHost())
{
STKHost::get()->shutdown();
}
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndSetStack(
NetworkConfig::get()->getResetScreens().data());
NetworkConfig::get()->unsetNetworking();
}
return;
}
// If something was unlocked, the 'continue' button was
// actually used to display "Show unlocked feature(s)" text.
// ---------------------------------------------------------
@ -330,32 +358,6 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
name.c_str());
}
// If we're playing online :
if (World::getWorld()->isNetworkWorld())
{
if (name == "middle") // Continue button (return to server lobby)
{
// Signal to the server that this client is back in the lobby now.
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl)
cl->doneWithResults();
getWidget("middle")->setText(_("Waiting for others"));
}
if (name == "bottom") // Quit server (return to online lan / wan menu)
{
if (STKHost::existHost())
{
STKHost::get()->shutdown();
}
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndSetStack(
NetworkConfig::get()->getResetScreens().data());
NetworkConfig::get()->unsetNetworking();
}
return;
}
// Next check for GP
// -----------------
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
@ -426,11 +428,20 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
*/
void RaceResultGUI::backToLobby()
{
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX &&
race_manager->getTrackNumber() == race_manager->getNumOfTracks() - 1)
{
core::stringw msg = _("Network grand prix has been finished.");
MessageQueue::add(MessageQueue::MT_ACHIEVEMENT, msg);
}
race_manager->clearNetworkGrandPrixResult();
race_manager->exitRace();
race_manager->setAIKartOverride("");
GUIEngine::ModalDialog::dismiss();
cleanupGPProgress();
StateManager::get()->resetAndSetStack(
NetworkConfig::get()->getResetScreens(true/*lobby*/).data());
NetworkingLobby::getInstance()->addMoreServerInfo(L"--------------------");
} // backToLobby
//-----------------------------------------------------------------------------
@ -1467,9 +1478,16 @@ void RaceResultGUI::backToLobby()
("sshot_" + StringUtils::toString(n_sshot)).c_str());
GUIEngine::LabelWidget* label = getWidget<GUIEngine::LabelWidget>(
("sshot_label_" + StringUtils::toString(n_sshot)).c_str());
assert(track != NULL && sshot != NULL && label != NULL);
assert(sshot != NULL && label != NULL);
sshot->setImage(track->getScreenshotFile());
// Network grand prix chooses each track 1 by 1
if (track == NULL)
{
sshot->setImage(file_manager->getAsset(FileManager::GUI,
"main_help.png"));
}
else
sshot->setImage(track->getScreenshotFile());
if (i <= currentTrack)
sshot->setBadge(GUIEngine::OK_BADGE);
else