Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2018-11-13 17:55:56 +11:00
commit 5c14ce86d7
127 changed files with 20082 additions and 18668 deletions

View File

@ -53,15 +53,23 @@
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Deadzone"/>
<div proportion="1" align="center" height="fit" layout="horizontal-row" >
<spacer width="40" height="10" />
<gauge id="deadzone_center" proportion="1" min_value="0" max_value="50"/>
<gauge id="deadzone" proportion="1" min_value="0" max_value="50"/>
</div>
</div>
<div width="75%" layout="horizontal-row" proportion="1">
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Sensitivity"/>
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Sensitivity X"/>
<div proportion="1" align="center" height="fit" layout="horizontal-row" >
<spacer width="40" height="10" />
<gauge id="deadzone_edge" proportion="1" min_value="0" max_value="50"/>
<gauge id="sensitivity_x" proportion="1" min_value="0" max_value="100"/>
</div>
</div>
<div width="75%" layout="horizontal-row" proportion="1">
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Sensitivity Y"/>
<div proportion="1" align="center" height="fit" layout="horizontal-row" >
<spacer width="40" height="10" />
<gauge id="sensitivity_y" proportion="1" min_value="0" max_value="100"/>
</div>
</div>

View File

@ -5,14 +5,12 @@
<model id="model" width="100%" layout="horizontal-row" height="100%">
</model>
</div>
<div width="20%" height="fit" text-align="left" layout="horizontal-row" >
<checkbox id="toggle-slider" />
<spacer width="40"/>
<label id="toggle-text"/>
<div width="40%" height="fit" text-align="left" layout="horizontal-row" >
<spinner id="toggle-slider" width="100%" min_value="0" max_value="1" wrap_around="true"/>
</div>
<spacer height="30" width="10"/>
<div height="fit" width="100%" layout="horizontal-row">
<gauge id="color-slider" min_value="1" max_value="100" proportion="1"/>
<gauge id="color-slider" min_value="1" max_value="100" proportion="1" wrap_around="true"/>
</div>
<spacer height="30" width="10"/>
<button id="close" text="Apply" align="center"/>

View File

@ -1,29 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="100%" height="96%" layout="vertical-row">
<div x="2%" y="1%" width="96%" height="98%" layout="vertical-row">
<!-- The achievement's name is filled in the header at runtime -->
<header id="title" width="96%" height="10%" text_align="center"
word_wrap="true"/>
<header id="title" width="100%" align="center" text_align="center"/>
<spacer width="20" height="1%" />
<label id="description" width="90%" height="12%" align="center"
<label id="description" width="100%" proportion="2" align="center"
text_align="center" word_wrap="true" text=""/>
<spacer width="20" height="1%" />
<div width="100%" proportion="2" layout="vertical-row">
<div width="100%" height="100%" layout="horizontal-row">
<div width="66%" height="100%" layout="vertical-row">
<spacer width="20" proportion="1"/>
<label width="100%" align="center"
text_align="center" I18N="Objective shown in achievement dialog" text="Goal"/>
<spacer width="20" proportion="1"/>
<label id="main-goal-description" width="100%" align="center"
text_align="center" word_wrap="true" text=""/>
<spacer width="20" proportion="2"/>
</div>
<div width="33%" height="100%" layout="vertical-row">
<spacer width="20" proportion="1"/>
<label width="100%" align="center"
text_align="center" I18N="Progress shown in achievement dialog" text="Progress"/>
<spacer width="20" proportion="1"/>
<label id="main-goal-progress" width="100%" align="center"
text_align="center" word_wrap="true" text=""/>
<spacer width="20" proportion="2"/>
</div>
</div>
</div>
<box width="96%" height="64%" align="center" layout="vertical-row"
padding="6">
<box width="100%" proportion="3" align="center" layout="vertical-row">
<list id="progress-tree" x="0" y="0" width="100%" height="100%" word_wrap="true"/>
</box>
<spacer width="20" height="1%" />
<buttonbar id="options" width="90%" height="10%" align="center">
<icon-button id="ok" width="16" height="16"
<buttonbar id="options" width="100%" height="14%" align="center">
<icon-button id="ok" width="128" height="128"
icon="gui/icons/green_check.png" text="OK"
label_location="bottom"/>
</buttonbar>
<spacer width="20" height="1%" />
<spacer width="20" height="3%" />
</div>
</stkgui>

View File

@ -16,7 +16,7 @@
I18N="Main menu button" text="Singleplayer"/>
<icon-button id="multiplayer" width="128" height="128"
icon="gui/icons/menu_multi.png" focus_icon="gui/icons/menu_multi_focus.png"
I18N="Main menu button" text="Multiplayer"/>
I18N="Main menu button" text="Local Multiplayer"/>
<icon-button id="online" width="128" height="128"
icon="gui/icons/menu_online.png" focus_icon="gui/icons/menu_online_focus.png"
I18N="Main menu button" text="Online"/>

View File

@ -9,34 +9,34 @@
<header width="80%" text="Race Setup" align="center" text_align="center" />
<spacer height="10" width="25"/>
<spacer height="1%" width="25"/>
<div layout="horizontal-row" width="fit" height="fit" align="left">
<bright proportion="1" height="100%"
<div layout="horizontal-row" width="40%" height="fit" align="left">
<bright width="fit" height="100%"
I18N="In soccer setup screen" text="Soccer game type" text_align="left" />
<spacer width="2%" height="25"/>
<spinner id="time_enabled" proportion="1" wrap_around="true"/>
</div>
<div layout="horizontal-row" width="100%" height="fit" align="left">
<bright width="fit" height="100%"
I18N="In soccer setup screen" text="Number of goals to win" text_align="left" />
<spacer width="10" height="25"/>
<spinner id="goalamount" width="200" min_value="1" max_value="10"/>
<spacer width="2%" height="25"/>
<spinner id="goalamount" width="15%" min_value="1" max_value="10"/>
</div>
<div layout="horizontal-row" width="fit" height="fit" align="left">
<bright proportion="1" height="100%"
<div layout="horizontal-row" width="100%" height="fit" align="left">
<bright width="fit" height="100%"
I18N="In soccer setup screen" text="Maximum time (min.)" text_align="left" />
<spacer width="10" height ="25"/>
<spinner id="timeamount" width="200" min_value="1" max_value="15"/>
<spacer width="2%" height="25"/>
<spinner id="timeamount" width="15%" min_value="1" max_value="15"/>
</div>
<div layout="horizontal-row" width="fit" height="fit" align="left">
<bright proportion="1" height="100%"
I18N="In soccer setup screen" text="Game type (Goals limit / Time limit)" text_align="left" />
<spacer width="10" height="25"/>
<checkbox id="time_enabled"/>
</div>
<spacer height="10" width="25"/>
<spacer height="1%" width="25"/>
<bubble height="fit" width="100%" id="lblLeftRight" I18N="In soccer setup screen" text="Use left/right to choose your team and press fire" word_wrap="true" text_align="center"/>
<spacer height="10" width="25"/>
<spacer height="1%" width="25"/>
<div id="central_div" layout="horizontal-row" width="100%" proportion="1" align="center">
<roundedbox width="100%" layout="horizontal-row" height="100%">
@ -44,7 +44,7 @@
</roundedbox>
</div>
<spacer height="10" width="25"/>
<spacer height="1%" width="25"/>
<button id="continue" I18N="In soccer setup screen" text="Continue" align="center" width="60%"/>
</div>

View File

@ -7,19 +7,19 @@
<header width="80%" I18N="In the track and grand prix selection screen" text="Grand Prix"
align="center" text_align="center" />
<box width="100%" height="195" padding="0">
<scrollable_toolbar id="gps" height="175" y="10" x="10" width="98%" align="center" label_location="each"
<box width="100%" proportion="1" layout="vertical-row" padding="0">
<scrollable_toolbar id="gps" x="1%" y="1%" width="98%" height="98%" align="center" label_location="each"
square_items="true" child_width="175" child_height="120" />
</box>
<header width="100%" I18N="In the track and grand prix selection screen" text="All Tracks"
align="center" text_align="center" />
<box proportion="1" width="100%" layout="vertical-row" padding="1">
<box proportion="3" width="100%" layout="vertical-row" padding="1">
<ribbon_grid id="tracks" proportion="1" width="100%" square_items="true"
label_location="bottom" align="center" max_rows="3"
child_width="160" child_height="120" />
<spacer width="20" height="13" />
<spacer width="20" height="5%" />
</box>
<!-- Populated dynamically at runtime -->

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -188,9 +188,9 @@
<powerup collect-mode="new"/>
<!-- time: How long a switch is being effective.
items for each item list the index of the item it is switched with.
Order: giftbox, banana, big-nitro, small-nitro, bubble-gum, trigger,
nolok-bubble-gum, easter egg -->
<switch time="5" items="1 0 4 4 2 5 2 7"/>
Order: giftbox, banana, big-nitro, small-nitro, bubble-gum, nolok-bubble-gum,
easter egg, trigger-->
<switch time="5" items="1 0 4 4 2 2 6 7"/>
<!-- disappear-counter: How often bubblegum gets driven over before it disappears.
shield-time: How long the bubblegum shield lasts
@ -206,8 +206,13 @@
steering-reduction: Reduce a remote kart's steering by this factor
each frame. This helps reduces oversteering by high latency
clients when they only do minor steering adjustments.
max-moveable-objects: Maximum number of moveable objects in a track
when networking is on. Objects will be hidden if total count is
larger than this value.
-->
<networking state-frequency="10" steering-reduction="1.0"/>
<networking state-frequency="10"
steering-reduction="1.0"
max-moveable-objects="15"/>
<!-- The field od views for 1-4 player split screen. fov-3 is
actually not used (since 3 player split screen uses the
@ -541,6 +546,14 @@
<!-- List of default ports used, by default STK use random ports for client.
The server discovery port has to be the same across all clients and servers.
-->
<network server-discovery-port="2757" client-port="2758" server-port="2759"/>
<network-ports server-discovery-port="2757" client-port="2758" server-port="2759"/>
<!-- Configurable values used in SmoothNetworkBody class.
-->
<network-smoothing min-adjust-length="0.1"
max-adjust-length="4.0"
min-adjust-speed="0.3"
max-adjust-time="2.0"
adjust-length-threshold="4.0"/>
</config>

View File

@ -16,9 +16,6 @@ namespace irr
namespace video
{
// Static members
io::path CImageLoaderJPG::Filename;
//! constructor
CImageLoaderJPG::CImageLoaderJPG()
{
@ -108,10 +105,10 @@ void CImageLoaderJPG::error_exit (j_common_ptr cinfo)
void CImageLoaderJPG::output_message(j_common_ptr cinfo)
{
// display the error message.
c8 temp1[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, temp1);
core::stringc errMsg("JPEG FATAL ERROR in ");
errMsg += core::stringc(Filename);
//c8 temp1[JMSG_LENGTH_MAX];
//(*cinfo->err->format_message)(cinfo, temp1);
//core::stringc errMsg("JPEG FATAL ERROR in ");
//errMsg += core::stringc(Filename);
//os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR);
}
#endif // _IRR_COMPILE_WITH_LIBJPEG_
@ -145,8 +142,6 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file, bool skip_checking) cons
if (!file)
return 0;
Filename = file->getFileName();
u8 **rowPtr=0;
u8* input = new u8[file->getSize()];
file->read(input, file->getSize());

View File

@ -100,9 +100,6 @@ private:
data has been read. Often a no-op. */
static void term_source (j_decompress_ptr cinfo);
// Copy filename to have it around for error-messages
static io::path Filename;
#endif // _IRR_COMPILE_WITH_LIBJPEG_
};

View File

@ -123,6 +123,7 @@ MusicInformation::MusicInformation(const XMLNode *root,
MusicInformation::~MusicInformation()
{
std::lock_guard<std::mutex> lock(m_music_mutex);
if(m_normal_music) delete m_normal_music;
if(m_fast_music) delete m_fast_music;
} // ~MusicInformation
@ -146,6 +147,7 @@ void MusicInformation::startMusic()
m_time_since_faster = 0.0f;
m_mode = SOUND_NORMAL;
std::unique_lock<std::mutex> lock(m_music_mutex);
if (m_normal_music)
{
delete m_normal_music;
@ -180,9 +182,11 @@ void MusicInformation::startMusic()
{
m_normal_music = new MusicDummy();
}
lock.unlock();
if (m_normal_music->load(m_normal_filename) == false)
{
lock.lock();
delete m_normal_music;
m_normal_music = NULL;
Log::warn("MusicInformation", "Unable to load music %s, "
@ -206,6 +210,7 @@ void MusicInformation::startMusic()
return;
}
lock.lock();
#ifdef ENABLE_SOUND
if (UserConfigParams::m_enable_sound)
{
@ -216,9 +221,11 @@ void MusicInformation::startMusic()
{
m_fast_music = new MusicDummy();
}
lock.unlock();
if (m_fast_music->load(m_fast_filename) == false)
{
lock.lock();
delete m_fast_music;
m_fast_music = NULL;
Log::warn("MusicInformation", "Unabled to load fast music %s, not "
@ -281,6 +288,7 @@ void MusicInformation::update(float dt)
//-----------------------------------------------------------------------------
void MusicInformation::stopMusic()
{
std::lock_guard<std::mutex> lock(m_music_mutex);
if (m_normal_music != NULL)
{
m_normal_music->stopMusic();
@ -357,6 +365,7 @@ void MusicInformation::switchToFastMusic()
bool MusicInformation::isPlaying() const
{
std::lock_guard<std::mutex> lock(m_music_mutex);
return (m_normal_music != NULL && m_normal_music->isPlaying()) ||
(m_fast_music != NULL && m_fast_music->isPlaying());
}

View File

@ -19,6 +19,7 @@
#ifndef HEADER_MUSIC_INFORMATION_HPP
#define HEADER_MUSIC_INFORMATION_HPP
#include <mutex>
#include <string>
#include <stdexcept>
#include <vector>
@ -66,6 +67,7 @@ private:
/** Maximum pitch for faster music. */
float m_max_pitch;
static const int LOOP_FOREVER=-1;
mutable std::mutex m_music_mutex;
Music *m_normal_music,
*m_fast_music;
enum {SOUND_NORMAL, //!< normal music is played

View File

@ -38,7 +38,7 @@ MusicOggStream::MusicOggStream(float loop_start)
m_soundBuffers[0] = m_soundBuffers[1]= 0;
m_soundSource = -1;
m_pausedMusic = true;
m_playing = false;
m_playing.store(false);
m_loop_start = loop_start;
} // MusicOggStream
@ -168,7 +168,7 @@ bool MusicOggStream::release()
if(!m_error) ov_clear(&m_oggStream);
m_soundSource = -1;
m_playing = false;
m_playing.store(false);
return true;
} // release
@ -189,7 +189,7 @@ bool MusicOggStream::playMusic()
alSourcePlay(m_soundSource);
m_pausedMusic = false;
m_playing = true;
m_playing.store(true);
check("playMusic");
return true;
} // playMusic
@ -197,7 +197,7 @@ bool MusicOggStream::playMusic()
//-----------------------------------------------------------------------------
bool MusicOggStream::isPlaying()
{
return m_playing;
return m_playing.load();
/*
if (m_soundSource == -1) return false;
@ -212,14 +212,14 @@ bool MusicOggStream::isPlaying()
//-----------------------------------------------------------------------------
bool MusicOggStream::stopMusic()
{
m_playing = false;
m_playing.store(false);
return (release());
} // stopMusic
//-----------------------------------------------------------------------------
bool MusicOggStream::pauseMusic()
{
m_playing = false;
m_playing.store(false);
if (m_fileName == "")
{
// nothing is loaded
@ -234,7 +234,7 @@ bool MusicOggStream::pauseMusic()
//-----------------------------------------------------------------------------
bool MusicOggStream::resumeMusic()
{
m_playing = true;
m_playing.store(true);
if (m_fileName == "")
{

View File

@ -40,6 +40,8 @@
#endif
#include "audio/music.hpp"
#include <atomic>
/**
* \brief ogg files based implementation of the Music interface
* \ingroup audio
@ -78,7 +80,7 @@ private:
vorbis_info* m_vorbisInfo;
bool m_error;
bool m_playing;
std::atomic_bool m_playing;
ALuint m_soundBuffers[2];
ALuint m_soundSource;

View File

@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits>
#include <math.h>
#ifdef ENABLE_SOUND
@ -88,7 +89,7 @@ SFXManager::SFXManager()
// The sound manager initialises OpenAL
m_initialized = music_manager->initialized();
m_master_gain = UserConfigParams::m_sfx_volume;
m_last_update_time = -1.0f;
m_last_update_time = std::numeric_limits<uint64_t>::max();
// Init position, since it can be used before positionListener is called.
// No need to use lock here, since the thread will be created later.
m_listener_position.getData() = Vec3(0, 0, 0);
@ -477,10 +478,10 @@ void* SFXManager::mainLoop(void *obj)
{
// Wait some time to let other threads run, then queue an
// update event to keep music playing.
double t = StkTime::getRealTime();
uint64_t t = StkTime::getRealTimeMs();
StkTime::sleep(1);
t = StkTime::getRealTime() - t;
me->queue(SFX_UPDATE, (SFXBase*)NULL, float(t));
t = StkTime::getRealTimeMs() - t;
me->queue(SFX_UPDATE, (SFXBase*)NULL, float(t / 1000.0));
}
me->m_sfx_commands.lock();
PROFILER_POP_CPU_MARKER();
@ -833,16 +834,16 @@ void SFXManager::reallyUpdateNow(SFXCommand *current)
#ifdef ENABLE_SOUND
if (!UserConfigParams::m_enable_sound)
return;
if (m_last_update_time < 0.0)
if (m_last_update_time == std::numeric_limits<uint64_t>::max())
{
// first time
m_last_update_time = StkTime::getRealTime();
m_last_update_time = StkTime::getRealTimeMs();
}
double previous_update_time = m_last_update_time;
m_last_update_time = StkTime::getRealTime();
float dt = float(m_last_update_time - previous_update_time);
uint64_t previous_update_time = m_last_update_time;
m_last_update_time = StkTime::getRealTimeMs();
float dt = float(m_last_update_time - previous_update_time) / 1000.0f;
assert(current->m_command==SFX_UPDATE);
if (music_manager->getCurrentMusic())

View File

@ -218,7 +218,7 @@ private:
/** Thread id of the thread running in this object. */
Synchronised<pthread_t *> m_thread_id;
double m_last_update_time;
uint64_t m_last_update_time;
/** A conditional variable to wake up the main loop. */
pthread_cond_t m_cond_request;

View File

@ -253,6 +253,9 @@ void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,
std::vector<std::string>& karts,
std::vector<const ChallengeData*>& unlocked)
{
if (UserConfigParams::m_unlock_everything > 0)
return;
ChallengeData* c = NULL;
for (AllChallengesType::iterator it = m_all_challenges.begin();

View File

@ -152,11 +152,16 @@ void STKConfig::load(const std::string &filename)
CHECK_NEG(m_default_track_friction, "physics default-track-friction");
CHECK_NEG(m_physics_fps, "physics fps" );
CHECK_NEG(m_network_state_frequeny, "network state-frequency" );
CHECK_NEG(m_max_moveable_objects, "network max-moveable-objects");
CHECK_NEG(m_network_steering_reduction,"network steering-reduction" );
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
CHECK_NEG(m_solver_iterations, "physics: solver-iterations" );
CHECK_NEG(m_network_state_frequeny, "network solver-state-frequency" );
CHECK_NEG(m_solver_split_impulse_thresh,"physics: solver-split-impulse-threshold");
CHECK_NEG(m_snb_min_adjust_length, "network smoothing: min-adjust-length");
CHECK_NEG(m_snb_max_adjust_length, "network smoothing: max-adjust-length");
CHECK_NEG(m_snb_min_adjust_speed, "network smoothing: min-adjust-speed");
CHECK_NEG(m_snb_max_adjust_time, "network smoothing: max-adjust-time");
CHECK_NEG(m_snb_adjust_length_threshold, "network smoothing: adjust-length-threshold");
// Square distance to make distance checks cheaper (no sqrt)
m_default_kart_properties->checkAllSet(filename);
@ -199,6 +204,7 @@ void STKConfig::init_defaults()
m_donate_url = "";
m_password_reset_url = "";
m_network_state_frequeny = -100;
m_max_moveable_objects = -100;
m_solver_iterations = -100;
m_solver_set_flags = 0;
m_solver_reset_flags = 0;
@ -216,6 +222,9 @@ void STKConfig::init_defaults()
m_server_discovery_port = 2757;
m_client_port = 2758;
m_server_port = 2759;
m_snb_min_adjust_length = m_snb_max_adjust_length =
m_snb_min_adjust_speed = m_snb_max_adjust_time =
m_snb_adjust_length_threshold = UNDEFINED;
m_score_increase.clear();
m_leader_intervals.clear();
@ -436,6 +445,7 @@ void STKConfig::getAllData(const XMLNode * root)
if (const XMLNode *networking_node = root->getNode("networking"))
{
networking_node->get("state-frequency", &m_network_state_frequeny);
networking_node->get("max-moveable-objects", &m_max_moveable_objects);
networking_node->get("steering-reduction", &m_network_steering_reduction);
}
@ -477,19 +487,28 @@ void STKConfig::getAllData(const XMLNode * root)
tc->get("quality", &m_tc_quality);
}
if (const XMLNode *tc = root->getNode("network"))
if (const XMLNode *np = root->getNode("network-ports"))
{
unsigned server_discovery_port = 0;
unsigned client_port = 0;
unsigned server_port = 0;
tc->get("server-discovery-port", &server_discovery_port);
tc->get("client-port", &client_port);
tc->get("server-port", &server_port);
np->get("server-discovery-port", &server_discovery_port);
np->get("client-port", &client_port);
np->get("server-port", &server_port);
m_server_discovery_port = (uint16_t)server_discovery_port;
m_client_port = (uint16_t)client_port;
m_server_port = (uint16_t)server_port;
}
if (const XMLNode *ns = root->getNode("network-smoothing"))
{
ns->get("min-adjust-length", &m_snb_min_adjust_length);
ns->get("max-adjust-length", &m_snb_max_adjust_length);
ns->get("min-adjust-speed", &m_snb_min_adjust_speed);
ns->get("max-adjust-time", &m_snb_max_adjust_time);
ns->get("adjust-length-threshold", &m_snb_adjust_length_threshold);
}
// Get the default KartProperties
// ------------------------------
const XMLNode *node = root -> getNode("general-kart-defaults");

View File

@ -89,6 +89,9 @@ public:
/** How many state updates per second the server will send. */
int m_network_state_frequeny;
/** Maximum number of moveable objects in a track when networking is on. */
int m_max_moveable_objects;
/** In case of a network race, remote karts will get their steering somewhat
* reduced each frame. This reduces stutter when a kart only does small
* steering adjustments. */
@ -203,6 +206,11 @@ public:
std::vector<std::string> m_normal_ttf;
std::vector<std::string> m_digit_ttf;
/** Configurable values used in SmoothNetworkBody class. */
float m_snb_min_adjust_length, m_snb_max_adjust_length,
m_snb_min_adjust_speed, m_snb_max_adjust_time,
m_snb_adjust_length_threshold;
private:
/** True if stk_config has been loaded. This is necessary if the
* --stk-config command line parameter has been specified to avoid

View File

@ -498,17 +498,21 @@ namespace UserConfigParams
&m_multitouch_group,
"Multitouch mode: 0 = undefined, 1 = steering wheel, 2 = accelerometer, 3 = gyroscope"));
PARAM_PREFIX FloatUserConfigParam m_multitouch_deadzone_center
PARAM_DEFAULT( FloatUserConfigParam(0.1f, "multitouch_deadzone_center",
PARAM_PREFIX FloatUserConfigParam m_multitouch_deadzone
PARAM_DEFAULT( FloatUserConfigParam(0.1f, "multitouch_deadzone",
&m_multitouch_group,
"A parameter in range [0, 0.5] that determines the zone that is "
"considered as centered in steering button."));
PARAM_PREFIX FloatUserConfigParam m_multitouch_deadzone_edge
PARAM_DEFAULT( FloatUserConfigParam(0.1f, "multitouch_deadzone_edge",
PARAM_PREFIX FloatUserConfigParam m_multitouch_sensitivity_x
PARAM_DEFAULT( FloatUserConfigParam(0.1f, "multitouch_sensitivity_x",
&m_multitouch_group,
"A parameter in range [0, 0.5] that determines the zone that is "
"considered as max value in steering button."));
"A parameter in range [0, 1.0] that determines the sensitivity for x axis."));
PARAM_PREFIX FloatUserConfigParam m_multitouch_sensitivity_y
PARAM_DEFAULT( FloatUserConfigParam(0.65f, "multitouch_sensitivity_y",
&m_multitouch_group,
"A parameter in range [0, 1.0] that determines the sensitivity for y axis."));
PARAM_PREFIX FloatUserConfigParam m_multitouch_tilt_factor
PARAM_DEFAULT( FloatUserConfigParam(4.0f, "multitouch_tilt_factor",

View File

@ -20,6 +20,7 @@
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "race/race_manager.hpp"
#include "tracks/drive_graph.hpp"
#include "ICameraSceneNode.h"
@ -57,6 +58,8 @@ void CameraEnd::clearEndCameras()
void CameraEnd::readEndCamera(const XMLNode &root)
{
m_end_cameras.clear();
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG)
return;
for(unsigned int i=0; i<root.getNumNodes(); i++)
{
unsigned int index = i;

View File

@ -343,8 +343,12 @@ void DynamicRibbonWidget::buildInternalStructure()
// ---- determine column amount
const float row_height = (float)(m_h - m_label_height)/(float)m_row_amount;
float ratio_zoom = (float)row_height / (float)(m_child_height - m_label_height);
m_col_amount = (int)roundf( m_w / ( m_child_width*ratio_zoom ) );
float col_width = (float)(row_height * m_child_width / m_child_height);
// Give some margin for columns for better readability
col_width *= 1.2f;
m_col_amount = (int)floor( m_w / col_width );
// ajust column amount to not add more item slots than we actually need
const int item_count = (int) m_items.size();

View File

@ -173,7 +173,7 @@ void MultitouchDevice::reset()
}
m_orientation = 0.0f;
m_gyro_time = 0.0;
m_gyro_time = 0;
} // reset
// ----------------------------------------------------------------------------
@ -223,7 +223,9 @@ void MultitouchDevice::activateGyroscope()
#ifdef ANDROID
if (!m_android_device->isGyroscopeActive())
{
m_android_device->activateGyroscope(1.0f / 60); // Assume 60 FPS, some phones can do 90 and 120 FPS but we won't handle them now
// Assume 60 FPS, some phones can do 90 and 120 FPS but we won't handle
// them now
m_android_device->activateGyroscope(1.0f / 60);
}
#endif
}
@ -350,26 +352,33 @@ void MultitouchDevice::updateDeviceState(unsigned int event_id)
*/
void MultitouchDevice::updateConfigParams()
{
m_deadzone_center = UserConfigParams::m_multitouch_deadzone_center;
m_deadzone_center = std::min(std::max(m_deadzone_center, 0.0f), 0.5f);
m_deadzone = UserConfigParams::m_multitouch_deadzone;
m_deadzone = std::min(std::max(m_deadzone, 0.0f), 0.5f);
m_deadzone_edge = UserConfigParams::m_multitouch_deadzone_edge;
m_deadzone_edge = std::min(std::max(m_deadzone_edge, 0.0f), 0.5f);
m_sensitivity_x = UserConfigParams::m_multitouch_sensitivity_x;
m_sensitivity_x = std::min(std::max(m_sensitivity_x, 0.0f), 1.0f);
m_sensitivity_y = UserConfigParams::m_multitouch_sensitivity_y;
m_sensitivity_y = std::min(std::max(m_sensitivity_y, 0.0f), 1.0f);
} // updateConfigParams
// ----------------------------------------------------------------------------
/** Helper function that returns a steering factor for steering button.
* \param value The axis value from 0 to 1.
* \param sensitivity Value from 0 to 1.0.
*/
float MultitouchDevice::getSteeringFactor(float value)
float MultitouchDevice::getSteeringFactor(float value, float sensitivity)
{
if (m_deadzone_edge + m_deadzone_center >= 1.0f)
if (m_deadzone >= 1.0f)
return 0.0f;
if (sensitivity >= 1.0f)
return 1.0f;
assert(m_deadzone_edge + m_deadzone_center != 1.0f);
return std::min((value - m_deadzone_center) / (1.0f - m_deadzone_edge -
m_deadzone_center), 1.0f);
float factor = (value - m_deadzone) / (1.0f - m_deadzone);
factor *= 1.0f / (1.0f - sensitivity);
return std::min(factor, 1.0f);
}
// ----------------------------------------------------------------------------
@ -379,15 +388,15 @@ void MultitouchDevice::updateAxisX(float value)
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
if (value < -m_deadzone)
{
float factor = getSteeringFactor(std::abs(value));
float factor = getSteeringFactor(std::abs(value), m_sensitivity_x);
m_controller->action(PA_STEER_RIGHT, 0);
m_controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
else if (value > m_deadzone)
{
float factor = getSteeringFactor(std::abs(value));
float factor = getSteeringFactor(std::abs(value), m_sensitivity_x);
m_controller->action(PA_STEER_LEFT, 0);
m_controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
@ -405,14 +414,14 @@ void MultitouchDevice::updateAxisY(float value)
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
if (value < -m_deadzone)
{
float factor = getSteeringFactor(std::abs(value));
float factor = getSteeringFactor(std::abs(value), m_sensitivity_y);
m_controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
else if (value > m_deadzone)
{
float factor = getSteeringFactor(std::abs(value));
float factor = getSteeringFactor(std::abs(value), m_sensitivity_y);
m_controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
@ -420,11 +429,13 @@ void MultitouchDevice::updateAxisY(float value)
m_controller->action(PA_BRAKE, 0);
m_controller->action(PA_ACCEL, 0);
}
}
// ----------------------------------------------------------------------------
/** Returns device orientation Z angle, in radians, where 0 is landscape orientation parallel to the floor.
/** Returns device orientation Z angle, in radians, where 0 is landscape
* orientation parallel to the floor.
*/
float MultitouchDevice::getOrientation()
{
@ -441,14 +452,14 @@ float MultitouchDevice::getOrientation()
void MultitouchDevice::updateOrientationFromAccelerometer(float x, float y)
{
const float ACCEL_DISCARD_THRESHOLD = 4.0f;
const float ACCEL_MULTIPLIER = 0.05f; // Slowly adjust the angle over time, this prevents shaking
const float ACCEL_MULTIPLIER = 0.05f; // Slowly adjust the angle over time,
// this prevents shaking
const float ACCEL_CHANGE_THRESHOLD = 0.01f; // ~0.5 degrees
// The device is flat on the table, cannot reliably determine the
// orientation
if (fabsf(x) + fabsf(y) < ACCEL_DISCARD_THRESHOLD)
{
// The device is flat on the table, cannot reliably determine the orientation
return;
}
float angle = atan2f(y, x);
if (angle > (M_PI / 2.0))
@ -473,7 +484,8 @@ void MultitouchDevice::updateOrientationFromAccelerometer(float x, float y)
m_orientation += delta;
//Log::warn("Accel", "X %03.4f Y %03.4f angle %03.4f delta %03.4f orientation %03.4f", x, y, angle, delta, m_orientation);
//Log::warn("Accel", "X %03.4f Y %03.4f angle %03.4f delta %03.4f "
// "orientation %03.4f", x, y, angle, delta, m_orientation);
}
// ----------------------------------------------------------------------------
@ -486,9 +498,10 @@ void MultitouchDevice::updateOrientationFromGyroscope(float z)
{
const float GYRO_SPEED_THRESHOLD = 0.005f;
double now = StkTime::getRealTime();
float timedelta = now - m_gyro_time;
uint64_t now = StkTime::getRealTimeMs();
uint64_t delta = now - m_gyro_time;
m_gyro_time = now;
float timedelta = (float)delta / 1000.f;
if (timedelta > 0.5f)
{
timedelta = 0.1f;
@ -511,7 +524,9 @@ void MultitouchDevice::updateOrientationFromGyroscope(float z)
m_orientation = -(M_PI / 2.0);
}
//Log::warn("Gyro", "Z %03.4f angular_speed %03.4f delta %03.4f orientation %03.4f", z, angular_speed, angular_speed * timedelta, m_orientation);
//Log::warn("Gyro", "Z %03.4f angular_speed %03.4f delta %03.4f "
// "orientation %03.4f", z, angular_speed,
// angular_speed * timedelta, m_orientation);
}
// ----------------------------------------------------------------------------

View File

@ -23,6 +23,7 @@
#include <vector>
#include "input/input_device.hpp"
#include "utils/types.hpp"
#include "IEventReceiver.h"
#ifdef ANDROID
@ -81,21 +82,23 @@ private:
/** The parameter that is used for steering button and determines dead area
* in a center of button */
float m_deadzone_center;
float m_deadzone;
/** The parameter that is used for steering button and determines dead area
* at the edge of button */
float m_deadzone_edge;
/** A parameter in range that determines the sensitivity for x axis. */
float m_sensitivity_x;
/** A parameter in range that determines the sensitivity for y axis. */
float m_sensitivity_y;
float m_orientation;
double m_gyro_time;
uint64_t m_gyro_time;
#ifdef ANDROID
/** Pointer to the Android irrlicht device */
CIrrDeviceAndroid* m_android_device;
#endif
float getSteeringFactor(float value);
float getSteeringFactor(float value, float sensitivity);
void handleControls(MultitouchButton* button);
bool isGameRunning();

View File

@ -70,7 +70,7 @@ void ItemState::setDisappearCounter()
m_used_up_counter = -1;
} // switch
} // setDisappearCounter
// -----------------------------------------------------------------------
/** Initialises an item.
* \param type Type for this item.
@ -157,24 +157,21 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
m_was_available_previously = true;
m_distance_2 = 1.2f;
initItem(type, xyz);
m_graphical_type = type;
m_original_rotation = shortestArcQuat(Vec3(0, 1, 0), normal);
m_rotation_angle = 0.0f;
m_original_mesh = mesh;
m_original_lowmesh = lowres_mesh;
m_listener = NULL;
LODNode* lodnode =
LODNode* lodnode =
new LODNode("item", irr_driver->getSceneManager()->getRootSceneNode(),
irr_driver->getSceneManager());
scene::ISceneNode* meshnode =
scene::ISceneNode* meshnode =
irr_driver->addMesh(mesh, StringUtils::insertValues("item_%i", (int)type));
if (lowres_mesh != NULL)
{
lodnode->add(35, meshnode, true);
scene::ISceneNode* meshnode =
irr_driver->addMesh(lowres_mesh,
scene::ISceneNode* meshnode =
irr_driver->addMesh(lowres_mesh,
StringUtils::insertValues("item_lo_%i", (int)type));
lodnode->add(100, meshnode, true);
}
@ -184,6 +181,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
}
m_node = lodnode;
setType(type);
handleNewMesh(getType());
#ifdef DEBUG
std::string debug_name("item: ");
@ -209,10 +207,8 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
{
m_distance_2 = distance*distance;
initItem(ITEM_TRIGGER, xyz);
m_graphical_type = ITEM_TRIGGER;
m_original_rotation = btQuaternion(0, 0, 0, 1);
m_rotation_angle = 0.0f;
m_original_mesh = NULL;
m_original_lowmesh = NULL;
m_node = NULL;
m_listener = trigger;
m_was_available_previously = true;
@ -226,8 +222,6 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
void Item::initItem(ItemType type, const Vec3 &xyz)
{
ItemState::initItem(type, xyz);
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
(getType()!=ITEM_TRIGGER );
// Now determine in which quad this item is, and its distance
// from the center within this quad.
m_graph_node = Graph::UNKNOWN_SECTOR;
@ -258,68 +252,13 @@ void Item::initItem(ItemType type, const Vec3 &xyz)
} // initItem
//-----------------------------------------------------------------------------
/** Sets the type of the item (and also derived attributes lile m_rotate
* \param type Type of the item.
*/
void Item::setType(ItemType type)
{
ItemState::setType(type);
m_rotate = (type!=ITEM_BUBBLEGUM) && (type!=ITEM_TRIGGER);
if (m_node != NULL)
{
for (auto* node : m_node->getAllNodes())
{
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(node);
if (spmn)
{
spmn->setGlowColor(ItemManager::get()->getGlowColor(type));
}
}
}
} // setType
//-----------------------------------------------------------------------------
/** Changes this item to be a new type for a certain amount of time.
* \param type New type of this item.
* \param mesh Mesh to use to display this item.
*/
void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh)
{
setMesh(mesh, lowmesh);
ItemState::switchTo(type, mesh, lowmesh);
} // switchTo
//-----------------------------------------------------------------------------
/** Switch backs to the original item. Returns true if the item wa snot
* actually switched (e.g. trigger, or bubblegum dropped during switch
* time). The return value is not actually used, but necessary in order
* to overwrite ItemState::switchBack()
*/
bool Item::switchBack()
{
setMesh(m_original_mesh, m_original_lowmesh);
if (ItemState::switchBack())
return true;
if (m_node != NULL)
{
Vec3 hpr;
hpr.setHPR(m_original_rotation);
m_node->setRotation(hpr.toIrrHPR());
}
return false;
} // switchBack
//-----------------------------------------------------------------------------
void Item::setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh)
{
#ifndef SERVER_ONLY
if (m_node == NULL)
return;
unsigned i = 0;
for (auto* node : m_node->getAllNodes())
{
@ -365,14 +304,35 @@ void Item::reset()
{
m_was_available_previously = true;
ItemState::reset();
if (m_node != NULL)
{
m_node->setScale(core::vector3df(1,1,1));
m_node->setVisible(true);
}
} // reset
// ----------------------------------------------------------------------------
void Item::handleNewMesh(ItemType type)
{
#ifndef SERVER_ONLY
if (m_node == NULL)
return;
setMesh(ItemManager::get()->getItemModel(type),
ItemManager::get()->getItemLowResolutionModel(type));
for (auto* node : m_node->getAllNodes())
{
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(node);
if (spmn)
spmn->setGlowColor(ItemManager::get()->getGlowColor(type));
}
Vec3 hpr;
hpr.setHPR(m_original_rotation);
m_node->setRotation(hpr.toIrrHPR());
#endif
} // handleNewMesh
// ----------------------------------------------------------------------------
/** Updated the item - rotates it, takes care of items coming back into
* the game after it has been collected.
@ -383,9 +343,15 @@ void Item::updateGraphics(float dt)
if (m_node == NULL)
return;
if (m_graphical_type != getType())
{
handleNewMesh(getType());
m_graphical_type = getType();
}
float time_till_return = stk_config->ticks2Time(getTicksTillReturn());
bool is_visible = isAvailable() || time_till_return <= 1.0f ||
(getType() == ITEM_BUBBLEGUM &&
bool is_visible = isAvailable() || time_till_return <= 1.0f ||
(getType() == ITEM_BUBBLEGUM &&
getOriginalType() == ITEM_NONE && !isUsedUp());
m_node->setVisible(is_visible);
@ -400,18 +366,32 @@ void Item::updateGraphics(float dt)
if (!isAvailable() && time_till_return <= 1.0f)
{
// Make it visible by scaling it from 0 to 1:
if (rotating())
{
float angle =
fmodf((float)(World::getWorld()->getTicksSinceStart() +
getTicksTillReturn()) / 40.0f, M_PI * 2);
btMatrix3x3 m;
m.setRotation(m_original_rotation);
btQuaternion r = btQuaternion(m.getColumn(1), angle) *
m_original_rotation;
Vec3 hpr;
hpr.setHPR(r);
m_node->setRotation(hpr.toIrrHPR());
}
m_node->setVisible(true);
m_node->setScale(core::vector3df(1, 1, 1)*(1 - time_till_return));
}
if (isAvailable() && m_rotate)
if (isAvailable() && rotating())
{
// have it rotate
m_rotation_angle += dt * M_PI;
if (m_rotation_angle > M_PI * 2) m_rotation_angle -= M_PI * 2;
float angle =
fmodf((float)World::getWorld()->getTicksSinceStart() / 40.0f,
M_PI * 2);
btMatrix3x3 m;
m.setRotation(m_original_rotation);
btQuaternion r = btQuaternion(m.getColumn(1), m_rotation_angle) *
btQuaternion r = btQuaternion(m.getColumn(1), angle) *
m_original_rotation;
Vec3 hpr;
@ -419,21 +399,4 @@ void Item::updateGraphics(float dt)
m_node->setRotation(hpr.toIrrHPR());
} // if item is available
m_was_available_previously = isAvailable();
} // update
//-----------------------------------------------------------------------------
/** Is called when the item is hit by a kart. It sets the flag that the item
* has been collected, and the time to return to the parameter.
* \param kart The kart that collected the item.
*/
void Item::collected(const AbstractKart *kart)
{
ItemState::collected(kart);
if (m_listener != NULL)
{
m_listener->onTriggerItemApproached();
}
} // isCollected
} // updateGraphics

View File

@ -202,7 +202,7 @@ public:
// -----------------------------------------------------------------------
/** Resets an item to its start state. */
void reset()
virtual void reset()
{
m_deactive_ticks = 0;
m_ticks_till_return = 0;
@ -219,11 +219,8 @@ public:
/** Switches an item to be of a different type. Used for the switch
* powerup.
* \param type New type for this item.
* \param mesh Ignored.
* \param lowmesh Ignored.
*/
virtual void switchTo(ItemType type, scene::IMesh *mesh,
scene::IMesh *lowmesh)
virtual void switchTo(ItemType type)
{
// triggers and easter eggs should not be switched
if (m_type == ITEM_TRIGGER || m_type == ITEM_EASTER_EGG) return;
@ -326,18 +323,11 @@ private:
* rotation). */
btQuaternion m_original_rotation;
/** Used when rotating the item */
float m_rotation_angle;
/** Scene node of this item. */
LODNode *m_node;
/** Stores the original mesh in order to reset it. */
scene::IMesh *m_original_mesh;
scene::IMesh *m_original_lowmesh;
/** Set to false if item should not rotate. */
bool m_rotate;
/** Graphical type of the mesh. */
ItemType m_graphical_type;
/** Stores if the item was available in the previously rendered frame. */
bool m_was_available_previously;
@ -360,9 +350,9 @@ private:
* would not be collected. Used by the AI to avoid items. */
Vec3 *m_avoidance_points[2];
void setType(ItemType type) OVERRIDE;
void initItem(ItemType type, const Vec3 &xyz);
void setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh);
void handleNewMesh(ItemType type);
public:
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
@ -373,12 +363,31 @@ public:
TriggerItemListener* trigger);
virtual ~Item ();
virtual void updateGraphics(float dt) OVERRIDE;
virtual void collected(const AbstractKart *kart) OVERRIDE;
void reset();
virtual void switchTo(ItemType type, scene::IMesh *mesh,
scene::IMesh *lowmesh) OVERRIDE;
virtual bool switchBack() OVERRIDE;
virtual void reset() OVERRIDE;
//-------------------------------------------------------------------------
/** Is called when the item is hit by a kart. It sets the flag that the
* item has been collected, and the time to return to the parameter.
* \param kart The kart that collected the item.
*/
virtual void collected(const AbstractKart *kart) OVERRIDE
{
ItemState::collected(kart);
if (m_listener != NULL)
m_listener->onTriggerItemApproached();
} // isCollected
//-------------------------------------------------------------------------
/** Switch backs to the original item. Returns true if the item was not
* actually switched (e.g. trigger, or bubblegum dropped during switch
* time). The return value is not actually used, but necessary in order
* to overwrite ItemState::switchBack()
*/
virtual bool switchBack() OVERRIDE
{
if (ItemState::switchBack())
return true;
return false;
} // switchBack
// ------------------------------------------------------------------------
/** Returns true if the Kart is close enough to hit this item, the item is
* not deactivated anymore, and it wasn't placed by this kart (this is
@ -397,6 +406,9 @@ public:
lc.setY(lc.getY() / 2.0f);
return lc.length2() < m_distance_2;
} // hitKart
// ------------------------------------------------------------------------
bool rotating() const
{ return getType() != ITEM_BUBBLEGUM && getType() != ITEM_TRIGGER; }
public:
// ------------------------------------------------------------------------

View File

@ -53,6 +53,7 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
} // is not switch
else // switch
{
m_index = -1;
m_kart_id = -1;
}
} // ItemEventInfo(BareNetworkString, int *count)

View File

@ -307,8 +307,7 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
if(m_switch_ticks>=0)
{
ItemState::ItemType new_type = m_switch_to[item->getType()];
item->switchTo(new_type, m_item_mesh[(int)new_type],
m_item_lowres_mesh[(int)new_type]);
item->switchTo(new_type);
}
return item;
} // dropNewItem
@ -338,8 +337,7 @@ Item* ItemManager::placeItem(ItemState::ItemType type, const Vec3& xyz,
if (m_switch_ticks >= 0)
{
ItemState::ItemType new_type = m_switch_to[item->getType()];
item->switchTo(new_type, m_item_mesh[(int)new_type],
m_item_lowres_mesh[(int)new_type]);
item->switchTo(new_type);
}
return item;
} // placeItem
@ -575,8 +573,7 @@ void ItemManager::switchItemsInternal(std::vector<ItemState*> &all_items)
if (new_type == (*i)->getType())
continue;
if(m_switch_ticks<0)
(*i)->switchTo(new_type, m_item_mesh[(int)new_type],
m_item_lowres_mesh[(int)new_type]);
(*i)->switchTo(new_type);
else
(*i)->switchBack();
} // for all_items

View File

@ -45,15 +45,9 @@ class ItemManager : public NoCopy
{
// Some static data and functions to initialise it:
private:
/** Stores all item models. */
static std::vector<scene::IMesh *> m_item_mesh;
/** Stores the glow color for all items. */
static std::vector<video::SColorf> m_glow_color;
/** Stores all low-resolution item models. */
static std::vector<scene::IMesh *> m_item_lowres_mesh;
/** Disable item collection (for debugging purposes). */
static bool m_disable_item_collection;
@ -61,6 +55,7 @@ private:
protected:
/** The instance of ItemManager while a race is on. */
static std::shared_ptr<ItemManager> m_item_manager;
public:
static void loadDefaultItemMeshes();
static void removeTextures();
@ -84,6 +79,10 @@ public:
static scene::IMesh* getItemModel(ItemState::ItemType type)
{ return m_item_mesh[type]; }
// ------------------------------------------------------------------------
/** Returns the low resolution mesh for a certain item. */
static scene::IMesh* getItemLowResolutionModel(ItemState::ItemType type)
{ return m_item_lowres_mesh[type]; }
// ------------------------------------------------------------------------
/** Returns the glow color for an item. */
static video::SColorf& getGlowColor(ItemState::ItemType type)
{ return m_glow_color[type]; }
@ -102,14 +101,20 @@ protected:
typedef std::vector<ItemState*> AllItemTypes;
AllItemTypes m_all_items;
/** What item this item is switched to. */
std::vector<ItemState::ItemType> m_switch_to;
private:
/** Stores which items are on which quad. m_items_in_quads[#quads]
* contains all items that are not on a quad. Note that this
* field is undefined if no Graph exist, e.g. arena without navmesh. */
std::vector< AllItemTypes > *m_items_in_quads;
/** What item this item is switched to. */
std::vector<ItemState::ItemType> m_switch_to;
/** Stores all item models. */
static std::vector<scene::IMesh *> m_item_mesh;
/** Stores all low-resolution item models. */
static std::vector<scene::IMesh *> m_item_lowres_mesh;
protected:
/** Remaining time that items should remain switched. If the

View File

@ -371,7 +371,8 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
iei.getIndex(),
iei.getTicks(), iei.isItemCollection(), iei.isNewItem(),
iei.getTicksTillReturn(),
iei.getIndex() < (int)m_confirmed_state.size() ? m_confirmed_state[iei.getIndex()] : NULL);
iei.getIndex() < (int)m_confirmed_state.size() && iei.getIndex() != -1 ?
m_confirmed_state[iei.getIndex()] : NULL);
// 1.2) If the event needs to be applied, forward
// the time to the time of this event:
// ----------------------------------------------
@ -409,6 +410,11 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
ItemState *is = new ItemState(iei.getNewItemType(), kart,
iei.getIndex() );
is->initItem(iei.getNewItemType(), iei.getXYZ());
if (m_switch_ticks >= 0)
{
ItemState::ItemType new_type = m_switch_to[is->getType()];
is->switchTo(new_type);
}
// A new confirmed item must either be inserted at the end of all
// items, or in an existing unused entry.
@ -478,8 +484,6 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
? m_confirmed_state[i] : NULL;
if (is && item)
{
// TODO: Check that the item has the right model, otherwise it
// might be an incorrectly predicted item.
*(ItemState*)item = *is;
}
else if (is && !item)

View File

@ -281,6 +281,15 @@ int MaxSpeed::getSpeedIncreaseTicksLeft(unsigned int category)
return m_speed_increase[category].getTimeLeft();
} // getSpeedIncreaseTimeLeft
// ----------------------------------------------------------------------------
/** Returns if increased speed is active in the given category.
* \param category Which category to report on.
*/
int MaxSpeed::isSpeedIncreaseActive(unsigned int category)
{
return m_speed_increase[category].isActive();
} // isSpeedIncreaseActive
// ----------------------------------------------------------------------------
/** Returns if decreased speed is active in the given category.
* \param category Which category to report on.

View File

@ -192,6 +192,7 @@ public:
void setSlowdown(unsigned int category, float max_speed_fraction,
int fade_in_time, int duration=-1);
int getSpeedIncreaseTicksLeft(unsigned int category);
int isSpeedIncreaseActive(unsigned int category);
int isSpeedDecreaseActive(unsigned int category);
void update(int ticks);
void reset();

Some files were not shown because too many files have changed in this diff Show More