Synchronized random arena item in network game

This commit is contained in:
Benau 2018-07-14 08:11:35 +08:00
parent 9fbfe0588f
commit c72db7099d
6 changed files with 31 additions and 16 deletions

View File

@ -32,7 +32,6 @@
#include "tracks/arena_graph.hpp"
#include "tracks/arena_node.hpp"
#include "tracks/track.hpp"
#include "utils/random_generator.hpp"
#include "utils/string_utils.hpp"
#include <IMesh.h>
@ -49,7 +48,7 @@ std::vector<scene::IMesh *> ItemManager::m_item_lowres_mesh;
std::vector<video::SColorf> ItemManager::m_glow_color;
bool ItemManager::m_disable_item_collection = false;
ItemManager * ItemManager::m_item_manager = NULL;
std::mt19937 ItemManager::m_random_engine;
//-----------------------------------------------------------------------------
/** Creates one instance of the item manager. */
@ -577,11 +576,11 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
invalid_location.push_back(node);
}
RandomGenerator random;
const unsigned int ALL_NODES = ag->getNumNodes();
const unsigned int MIN_DIST = int(sqrt(ALL_NODES));
const unsigned int TOTAL_ITEM = MIN_DIST / 2;
std::vector<uint32_t> random_numbers;
Log::info("[ItemManager]","Creating %d random items for arena", TOTAL_ITEM);
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
{
@ -595,8 +594,9 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
"Use default item location.");
return false;
}
const int node = random.get(ALL_NODES);
uint32_t number = m_random_engine();
Log::debug("[ItemManager]", "%u from random engine.", number);
const int node = number % ALL_NODES;
// Check if tried
std::vector<int>::iterator it = std::find(invalid_location.begin(),
@ -622,6 +622,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
{
chosen_node = node;
invalid_location.push_back(node);
random_numbers.push_back(number);
break;
}
else
@ -635,7 +636,8 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
for (unsigned int i = 0; i < pos.size(); i++)
used_location.erase(used_location.begin());
assert (used_location.size() == TOTAL_ITEM);
assert(used_location.size() == TOTAL_ITEM);
assert(random_numbers.size() == TOTAL_ITEM);
// Hard-coded ratio for now
const int BONUS_BOX = 4;
@ -644,7 +646,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
for (unsigned int i = 0; i < TOTAL_ITEM; i++)
{
const int j = random.get(10);
const unsigned j = random_numbers[i] % 10;
ItemState::ItemType type = (j > BONUS_BOX ? ItemState::ITEM_BONUS_BOX :
j > NITRO_BIG ? ItemState::ITEM_NITRO_BIG :
j > NITRO_SMALL ? ItemState::ITEM_NITRO_SMALL : ItemState::ITEM_BANANA);

View File

@ -31,6 +31,7 @@
#include <assert.h>
#include <map>
#include <memory>
#include <random>
#include <string>
#include <vector>
@ -56,6 +57,7 @@ private:
/** Disable item collection (for debugging purposes). */
static bool m_disable_item_collection;
static std::mt19937 m_random_engine;
protected:
/** The instance of ItemManager while a race is on. */
static ItemManager *m_item_manager;
@ -64,6 +66,11 @@ public:
static void removeTextures();
static void create();
static void destroy();
static void updateRandomSeed(uint32_t seed_number)
{
m_random_engine.seed(seed_number);
} // updateRandomSeed
// ------------------------------------------------------------------------
/** Disable item collection, useful to test client mispreditions or
* client/server disagreements. */
@ -115,7 +122,6 @@ protected:
virtual ~ItemManager();
public:
virtual Item* placeItem (ItemState::ItemType type, const Vec3& xyz,
const Vec3 &normal);
virtual Item* dropNewItem (ItemState::ItemType type,

View File

@ -87,6 +87,8 @@ void GameSetup::loadWorld()
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER ||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES)
{
bool prev_val = UserConfigParams::m_random_arena_item;
UserConfigParams::m_random_arena_item = m_reverse;
race_manager->setReverseTrack(false);
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
{
@ -97,6 +99,7 @@ void GameSetup::loadWorld()
}
race_manager->startSingleRace(m_tracks.back(), -1,
false/*from_overworld*/);
UserConfigParams::m_random_arena_item = prev_val;
}
else
{

View File

@ -25,6 +25,7 @@
#include "guiengine/message_queue.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "input/device_manager.hpp"
#include "items/item_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/linear_world.hpp"
#include "network/crypto.hpp"
@ -241,6 +242,8 @@ void ClientLobby::addAllPlayers(Event* event)
m_game_setup->addPlayer(player);
players.push_back(player);
}
uint32_t random_seed = data.getUInt32();
ItemManager::updateRandomSeed(random_seed);
configRemoteKart(players);
loadWorld();
// Switch to assign mode in case a player hasn't chosen any karts
@ -427,7 +430,7 @@ void ClientLobby::displayPlayerVote(Event* event)
{
//I18N: Vote message in network game from a player
vote_msg = _("Track: %s,\n"
"maximum time: %d,random item location: %s",
"maximum time: %d,\nrandom item location: %s",
track_readable, lap, rev == 1 ? yes : no);
}
}

View File

@ -19,6 +19,7 @@
#include "network/protocols/server_lobby.hpp"
#include "config/user_config.hpp"
#include "items/item_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/linear_world.hpp"
#include "network/crypto.hpp"
@ -409,6 +410,9 @@ void ServerLobby::asynchronousUpdate()
}
load_world->encodeString(player->getKartName());
}
uint32_t random_seed = (uint32_t)StkTime::getTimeSinceEpoch();
ItemManager::updateRandomSeed(random_seed);
load_world->addUInt32(random_seed);
configRemoteKart(players);
// Reset for next state usage

View File

@ -1111,13 +1111,6 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
void Track::loadMinimap()
{
#ifndef SERVER_ONLY
//Check whether the hardware can do nonsquare or
// non power-of-two textures
video::IVideoDriver* const video_driver = irr_driver->getVideoDriver();
bool nonpower = false; //video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
bool nonsquare =
video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE);
//Create the minimap resizing it as necessary.
m_mini_map_size = World::getWorld()->getRaceGUI()->getMiniMapSize();
@ -1808,7 +1801,11 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
if (NetworkConfig::get()->isNetworking())
NetworkItemManager::create();
else
{
// Seed random engine locally
ItemManager::updateRandomSeed((uint32_t)StkTime::getTimeSinceEpoch());
ItemManager::create();
}
// Set the default start positions. Node that later the default
// positions can still be overwritten.