This commit is contained in:
Benau 2018-11-26 11:55:43 +08:00
parent 073708c97e
commit dba713f72e
6 changed files with 27 additions and 4 deletions

View File

@ -526,6 +526,7 @@ void Powerup::hitBonusBox(const ItemState &item_state)
// (1) The item id
// (2) The time
// (3) The position of the kart
// (4) An extra random 64bit integer
// Using (1) means that not all boxes at a certain time for a kart
// will give the same box. Using (2) means that the item will
// change over time - even if the next item is displayed, it
@ -533,7 +534,8 @@ void Powerup::hitBonusBox(const ItemState &item_state)
// of the time component it will also be difficult to get the
// item at the right time. Using (3) adds another cheat-prevention
// layer: even if a cheater is waiting for the right sequence
// of items, if he is overtaken the sequence will change.
// of items, if he is overtaken the sequence will change, using (4)
// to avoid same item sequence when starting
//
// In order to increase the probability of correct client prediction
// in networking (where there might be 1 or 2 frames difference
@ -544,7 +546,8 @@ 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.
uint64_t random_number = item_state.getItemId() * 31 +
world->getTicksSinceStart() / 10 + position * 23;
world->getTicksSinceStart() / 10 + position * 23 +
powerup_manager->getRandomSeed();
// Use this random number as a seed of a PRNG (based on the one in
// bullet's btSequentialImpulseConstraintSolver) to avoid getting

View File

@ -43,6 +43,7 @@ PowerupManager* powerup_manager=0;
/** The constructor initialises everything to zero. */
PowerupManager::PowerupManager()
{
m_random_seed.store(0);
for(int i=0; i<POWERUP_MAX; i++)
{
m_all_meshes[i] = NULL;

View File

@ -19,11 +19,13 @@
#ifndef HEADER_POWERUPMANAGER_HPP
#define HEADER_POWERUPMANAGER_HPP
#include "utils/no_copy.hpp"
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include "utils/types.hpp"
#include "btBulletDynamicsCommon.h"
#include <atomic>
#include <map>
#include <string>
#include <vector>
@ -151,6 +153,11 @@ private:
WeightsData m_current_item_weights;
PowerupType getPowerupType(const std::string &name) const;
/** Seed for random powerup, for local game it will use a random number,
* for network games it will use the start time from server. */
std::atomic<uint64_t> m_random_seed;
public:
static void unitTesting();
@ -171,6 +178,11 @@ public:
/** Returns the mesh for a certain powerup.
* \param type Mesh type for which the model is returned. */
irr::scene::IMesh *getMesh(int type) const {return m_all_meshes[type];}
// ------------------------------------------------------------------------
uint64_t getRandomSeed() const { return m_random_seed.load(); }
// ------------------------------------------------------------------------
void setRandomSeed(uint64_t seed) { m_random_seed.store(seed); }
}; // class PowerupManager
extern PowerupManager* powerup_manager;

View File

@ -26,6 +26,7 @@
#include "guiengine/screen_keyboard.hpp"
#include "input/device_manager.hpp"
#include "items/item_manager.hpp"
#include "items/powerup_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/linear_world.hpp"
#include "network/crypto.hpp"
@ -816,6 +817,7 @@ void ClientLobby::startGame(Event* event)
{
World::getWorld()->setPhase(WorldStatus::SERVER_READY_PHASE);
uint64_t start_time = event->data().getUInt64();
powerup_manager->setRandomSeed(start_time);
joinStartGameThread();
m_start_game_thread = std::thread([start_time, this]()
{

View File

@ -20,6 +20,7 @@
#include "config/user_config.hpp"
#include "items/item_manager.hpp"
#include "items/powerup_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/player_controller.hpp"
#include "karts/kart_properties_manager.hpp"
@ -2369,6 +2370,7 @@ void ServerLobby::configPeersStartTime()
// Start up time will be after 2500ms, so even if this packet is sent late
// (due to packet loss), the start time will still ahead of current time
uint64_t start_time = STKHost::get()->getNetworkTimer() + (uint64_t)2500;
powerup_manager->setRandomSeed(start_time);
NetworkString* ns = getNetworkString(10);
ns->addUInt8(LE_START_RACE).addUInt64(start_time);
sendMessageToPeers(ns, /*reliable*/true);

View File

@ -53,6 +53,7 @@
#include "items/item.hpp"
#include "items/item_manager.hpp"
#include "items/network_item_manager.hpp"
#include "items/powerup_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "modes/linear_world.hpp"
@ -1855,8 +1856,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
else
{
// Seed random engine locally
ItemManager::updateRandomSeed((uint32_t)StkTime::getTimeSinceEpoch());
uint32_t seed = (uint32_t)StkTime::getTimeSinceEpoch();
ItemManager::updateRandomSeed(seed);
ItemManager::create();
powerup_manager->setRandomSeed(seed);
}
// Set the default start positions. Node that later the default