Merge with latest master
This commit is contained in:
commit
fc969982da
@ -27,7 +27,7 @@
|
|||||||
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Buttons scale"/>
|
<label proportion="1" align="center" text_align="right" I18N="In the multitouch settings screen" text="Buttons scale"/>
|
||||||
<div proportion="1" align="center" height="fit" layout="horizontal-row" >
|
<div proportion="1" align="center" height="fit" layout="horizontal-row" >
|
||||||
<spacer width="40" height="10" />
|
<spacer width="40" height="10" />
|
||||||
<gauge id="scale" proportion="1" min_value="50" max_value="150"/>
|
<gauge id="scale" proportion="1" min_value="80" max_value="160"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<stkgui>
|
<stkgui>
|
||||||
<div y="2%" width="100%" height="96%" layout="vertical-row">
|
<div x="1%" y="2%" width="98%" height="96%" layout="vertical-row">
|
||||||
|
|
||||||
<div width="100%" height="40%" layout="vertical-row">
|
<div width="100%" height="40%" layout="vertical-row">
|
||||||
<div width="100%" height="25%" layout="vertical-row" >
|
<div width="100%" height="25%" layout="vertical-row" >
|
||||||
<label id="name" width="100%" text_align="center"/>
|
<label id="name" width="100%" text_align="center"/>
|
||||||
</div>
|
</div>
|
||||||
<!-- This is filled in programmatically -->
|
<!-- This is filled in programmatically -->
|
||||||
<box width="98%" height="75%" align="center" layout="vertical-row" padding="1">
|
<box width="100%" height="75%" align="center" layout="vertical-row" padding="1">
|
||||||
<list id="current_replay_info" x="0" y="0" width="100%" height="100%"/>
|
<list id="current_replay_info" x="0" y="0" width="100%" height="100%"/>
|
||||||
</box>
|
</box>
|
||||||
</div>
|
</div>
|
||||||
@ -18,8 +18,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div width="64%" height="100%" layout="vertical-row">
|
<div width="64%" height="100%" layout="vertical-row">
|
||||||
<div width="95%" align="center" layout="vertical-row" height="fit">
|
<div width="95%" align="center" layout="vertical-row" height="50%">
|
||||||
<div width="100%" height="40" layout="horizontal-row" >
|
<div width="100%" height="fit" layout="horizontal-row" >
|
||||||
<checkbox width="fit" id="record-race" I18N="Ghost replay info action" text_align="left"/>
|
<checkbox width="fit" id="record-race" I18N="Ghost replay info action" text_align="left"/>
|
||||||
<spacer width="10"/>
|
<spacer width="10"/>
|
||||||
<label proportion="1" id="record-race-text" height="100%" text_align="left" I18N="Ghost replay info action" text="Record the race for ghost replay"/>
|
<label proportion="1" id="record-race-text" height="100%" text_align="left" I18N="Ghost replay info action" text="Record the race for ghost replay"/>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div width="95%" height="50%" align="center">
|
<div width="95%" height="40%" align="center">
|
||||||
<buttonbar id="actions" x="0" y="0" height="100%" width="100%" align="center">
|
<buttonbar id="actions" x="0" y="0" height="100%" width="100%" align="center">
|
||||||
<icon-button id="start" width="128" height="128"
|
<icon-button id="start" width="128" height="128"
|
||||||
icon="gui/icons/green_check.png"
|
icon="gui/icons/green_check.png"
|
||||||
|
@ -13,50 +13,55 @@
|
|||||||
<list id="replay_list" x="0" y="0" width="100%" height="100%"/>
|
<list id="replay_list" x="0" y="0" width="100%" height="100%"/>
|
||||||
</box>
|
</box>
|
||||||
|
|
||||||
<tabs id="race_mode" height="6%" max_height="110" x="2%" width="98%" align="center">
|
<tabs id="race_mode" height="6%" max_height="110" x="1%" width="98%" align="center">
|
||||||
<icon-button id="tab_time_trial" width="128" height="128" icon="gui/icons/mode_tt.png"
|
<icon-button id="tab_time_trial" width="128" height="128" icon="gui/icons/mode_tt.png"
|
||||||
I18N="In the ghost replay selection screen" text="Time trial"/>
|
I18N="In the ghost replay selection screen" text="Time trial"/>
|
||||||
<icon-button id="tab_egg_hunt" width="128" height="128" icon="gui/icons/mode_easter.png"
|
<icon-button id="tab_egg_hunt" width="128" height="128" icon="gui/icons/mode_easter.png"
|
||||||
I18N="In the ghost replay selection screen" text="Egg hunt"/>
|
I18N="In the ghost replay selection screen" text="Egg hunt"/>
|
||||||
</tabs>
|
</tabs>
|
||||||
|
|
||||||
<spacer width="100%" height="1.5%" />
|
<spacer width="100%" height="2%" />
|
||||||
|
|
||||||
<div width="99%" align="center" layout="horizontal-row" height="fit">
|
<div width="98%" align="center" layout="horizontal-row" height="fit">
|
||||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
<div width="60%" height="fit" layout="horizontal-row" >
|
||||||
<checkbox width="fit" id="best_times_toggle" text_align="left"/>
|
<checkbox width="fit" id="best_times_toggle" text_align="left"/>
|
||||||
<spacer width="2%" height="fit"/>
|
<spacer width="2%" height="fit"/>
|
||||||
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show the best times"/>
|
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show the best times"/>
|
||||||
</div>
|
</div>
|
||||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
<div width="40%" height="fit" layout="horizontal-row" >
|
||||||
<checkbox width="fit" id="compare_toggle" text_align="left"/>
|
<checkbox width="fit" id="compare_toggle" text_align="left"/>
|
||||||
<spacer width="2%" height="fit"/>
|
<spacer width="2%" height="fit"/>
|
||||||
<label height="100%" id="compare-toggle-text" text_align="left" I18N="In the ghost replay selection screen" text="Compare replay"/>
|
<label height="100%" id="compare-toggle-text" text_align="left" I18N="In the ghost replay selection screen" text="Compare replay"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div width="99%" align="center" layout="horizontal-row" height="fit">
|
<div width="98%" align="center" layout="horizontal-row" height="fit">
|
||||||
<div proportion="2" height="fit" layout="horizontal-row" >
|
<div width="60%" height="fit" layout="horizontal-row" >
|
||||||
<checkbox width="fit" id="replay_difficulty_toggle" text_align="left"/>
|
<checkbox width="fit" id="replay_difficulty_toggle" text_align="left"/>
|
||||||
<spacer width="2%" height="fit"/>
|
<spacer width="2%" height="fit"/>
|
||||||
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current difficulty"/>
|
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current difficulty"/>
|
||||||
</div>
|
</div>
|
||||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
|
||||||
<checkbox width="fit" id="replay_multiplayer_toggle" text_align="left"/>
|
|
||||||
<spacer width="2%" height="fit"/>
|
|
||||||
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Hide multiplayer replays"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div width="99%" align="center" layout="horizontal-row" height="fit">
|
<div width="98%" align="center" layout="horizontal-row" height="fit">
|
||||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
<div width="60%" height="fit" layout="horizontal-row" >
|
||||||
<checkbox width="fit" id="replay_version_toggle" text_align="left"/>
|
<checkbox width="fit" id="replay_version_toggle" text_align="left"/>
|
||||||
<spacer width="1%" height="fit" />
|
<spacer width="2%" height="fit" />
|
||||||
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current version"/>
|
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Only show replays matching the current version"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button x="1%" id="record-ghost" I18N="In the ghost replay selection screen" text="Record a ghost replay"/>
|
<div width="98%" align="center" layout="horizontal-row" height="fit">
|
||||||
|
<div width="60%" height="fit" layout="horizontal-row" >
|
||||||
|
<checkbox width="fit" id="replay_multiplayer_toggle" text_align="left"/>
|
||||||
|
<spacer width="2%" height="fit"/>
|
||||||
|
<label height="100%" text_align="left" I18N="In the ghost replay selection screen" text="Hide multiplayer replays"/>
|
||||||
|
</div>
|
||||||
|
<div width="40%" height="fit" layout="horizontal-row" >
|
||||||
|
<spacer proportion="1" height="5"/>
|
||||||
|
<button width="fit" id="record-ghost" I18N="In the ghost replay selection screen" text="Record a ghost replay"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</stkgui>
|
</stkgui>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<checkbox width="fit" id="private_server" text_align="left"/>
|
<checkbox width="fit" id="private_server" text_align="left"/>
|
||||||
<spacer width="10"/>
|
<spacer width="10"/>
|
||||||
<label proportion="1" height="100%" text_align="left"
|
<label proportion="1" height="100%" text_align="left"
|
||||||
I18N="In the server selection screen" text="Show only private server(s)"/>
|
I18N="In the server selection screen" text="Show private server(s)"/>
|
||||||
<checkbox width="fit" id="game_started" text_align="left"/>
|
<checkbox width="fit" id="game_started" text_align="left"/>
|
||||||
<spacer width="10"/>
|
<spacer width="10"/>
|
||||||
<label proportion="1" height="100%" text_align="left"
|
<label proportion="1" height="100%" text_align="left"
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
The actual turn radius is piece-wise linearly interpolated. This
|
The actual turn radius is piece-wise linearly interpolated. This
|
||||||
allows for tighter turning at lower speeds, and also avoids that
|
allows for tighter turning at lower speeds, and also avoids that
|
||||||
the kart becomes too hard to control at high speed (speeds of
|
the kart becomes too hard to control at high speed (speeds of
|
||||||
higher than 23 can only be reached with powerups).
|
higher than 25 can only be reached with powerups).
|
||||||
time-full-steer: This is the amount of change in steering depending
|
time-full-steer: This is the amount of change in steering depending
|
||||||
on current steering. So if the steering is between 0 and 0.5,
|
on current steering. So if the steering is between 0 and 0.5,
|
||||||
the time-for-steering-change is 0.15. If the current steering is
|
the time-for-steering-change is 0.15. If the current steering is
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<!-- Minimum and maxium server versions that be be read by this binary.
|
<!-- Minimum and maxium server versions that be be read by this binary.
|
||||||
Older versions will be ignored. -->
|
Older versions will be ignored. -->
|
||||||
<server-version min="1" max="1"/>
|
<server-version min="2" max="2"/>
|
||||||
|
|
||||||
<!-- Maximum number of karts to be used at the same time. This limit
|
<!-- Maximum number of karts to be used at the same time. This limit
|
||||||
can easily be increased, but some tracks might not have valid start
|
can easily be increased, but some tracks might not have valid start
|
||||||
@ -114,7 +114,7 @@
|
|||||||
that the bit is to be set to 0, otherwise the bit will be set.
|
that the bit is to be set to 0, otherwise the bit will be set.
|
||||||
|
|
||||||
This field takes two
|
This field takes two
|
||||||
values: the first value is 'and'ed with bullet's default values
|
values: the first value is 'and'ed with bullet's default values
|
||||||
(i.e. it can be used to unset bullet defaults), the second value
|
(i.e. it can be used to unset bullet defaults), the second value
|
||||||
is 'or'ed (i.e. is used to set a bit). A value of -1 for 'and'
|
is 'or'ed (i.e. is used to set a bit). A value of -1 for 'and'
|
||||||
means to keep all bits. The valid names are listed in stk_config.cpp
|
means to keep all bits. The valid names are listed in stk_config.cpp
|
||||||
@ -125,7 +125,7 @@
|
|||||||
smooth-angle-limit="0.65"
|
smooth-angle-limit="0.65"
|
||||||
fps="120"
|
fps="120"
|
||||||
default-track-friction="0.5"
|
default-track-friction="0.5"
|
||||||
default-moveable-friction="0.5"
|
default-moveable-friction="0.5"
|
||||||
solver-iterations="4"
|
solver-iterations="4"
|
||||||
solver-split-impulse="true"
|
solver-split-impulse="true"
|
||||||
solver-split-impulse-threshold="-0.00001"
|
solver-split-impulse-threshold="-0.00001"
|
||||||
@ -149,14 +149,14 @@
|
|||||||
<replay max-frames="12000" delta-t="0.200" delta-speed="0.6"
|
<replay max-frames="12000" delta-t="0.200" delta-speed="0.6"
|
||||||
delta-steering="0.35" />
|
delta-steering="0.35" />
|
||||||
|
|
||||||
<!-- Determines the minimap related values.
|
<!-- Determines the minimap related values.
|
||||||
size: The size of the minimap (scaled afterwards) 480 = full screen height)
|
size: The size of the minimap (scaled afterwards) 480 = full screen height)
|
||||||
ai-icon: The size of the icons for the AI karts on the minimap.
|
ai-icon: The size of the icons for the AI karts on the minimap.
|
||||||
player-icon: The size of the icons for the player karts. -->
|
player-icon: The size of the icons for the player karts. -->
|
||||||
|
|
||||||
<minimap size="180.0" ai-icon="16.0" player-icon="20.0"/>
|
<minimap size="180.0" ai-icon="16.0" player-icon="20.0"/>
|
||||||
|
|
||||||
<urls donate="https://supertuxkart.net/Donate"
|
<urls donate="https://supertuxkart.net/Donate"
|
||||||
password-reset="http://addons.supertuxkart.net/password-reset.php" />
|
password-reset="http://addons.supertuxkart.net/password-reset.php" />
|
||||||
|
|
||||||
<!-- Skidmark data: maximum number of skid marks, and
|
<!-- Skidmark data: maximum number of skid marks, and
|
||||||
@ -201,7 +201,7 @@
|
|||||||
away if there is an explosion. -->
|
away if there is an explosion. -->
|
||||||
<explosion impulse-objects="500.0" />
|
<explosion impulse-objects="500.0" />
|
||||||
|
|
||||||
<!-- Networking
|
<!-- Networking
|
||||||
state-frequency: how many states the server will send per second.
|
state-frequency: how many states the server will send per second.
|
||||||
steering-reduction: Reduce a remote kart's steering by this factor
|
steering-reduction: Reduce a remote kart's steering by this factor
|
||||||
each frame. This helps reduces oversteering by high latency
|
each frame. This helps reduces oversteering by high latency
|
||||||
|
@ -133,6 +133,20 @@ namespace scene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void recursiveUpdateAbsolutePosition()
|
||||||
|
{
|
||||||
|
if (IsVisible)
|
||||||
|
{
|
||||||
|
// update absolute position
|
||||||
|
updateAbsolutePosition();
|
||||||
|
|
||||||
|
// perform the post render process on all children
|
||||||
|
|
||||||
|
ISceneNodeList::Iterator it = Children.begin();
|
||||||
|
for (; it != Children.end(); ++it)
|
||||||
|
(*it)->recursiveUpdateAbsolutePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Renders the node.
|
//! Renders the node.
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
@ -249,6 +249,10 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
|
|||||||
LastTimeMs = timeMs;
|
LastTimeMs = timeMs;
|
||||||
|
|
||||||
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
IAnimatedMeshSceneNode::OnAnimate(timeMs);
|
||||||
|
|
||||||
|
// For up-to-date current frame bone-child attachment
|
||||||
|
for (u32 n=0;n<JointChildSceneNodes.size();++n)
|
||||||
|
JointChildSceneNodes[n]->recursiveUpdateAbsolutePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,6 +186,9 @@ void CIrrDeviceAndroid::createVideoModeList()
|
|||||||
|
|
||||||
int width = ANativeWindow_getWidth(Android->window);
|
int width = ANativeWindow_getWidth(Android->window);
|
||||||
int height = ANativeWindow_getHeight(Android->window);
|
int height = ANativeWindow_getHeight(Android->window);
|
||||||
|
|
||||||
|
os::Printer::log("Window width:", core::stringc(width).c_str(), ELL_DEBUG);
|
||||||
|
os::Printer::log("Window height:", core::stringc(height).c_str(), ELL_DEBUG);
|
||||||
|
|
||||||
if (width > 0 && height > 0)
|
if (width > 0 && height > 0)
|
||||||
{
|
{
|
||||||
|
@ -762,7 +762,7 @@ namespace UserConfigParams
|
|||||||
&m_network_group, "Use random port for server connection "
|
&m_network_group, "Use random port for server connection "
|
||||||
"(check stk_config.xml for default value)"));
|
"(check stk_config.xml for default value)"));
|
||||||
PARAM_PREFIX BoolUserConfigParam m_lobby_chat
|
PARAM_PREFIX BoolUserConfigParam m_lobby_chat
|
||||||
PARAM_DEFAULT(BoolUserConfigParam(false, "lobby-chat",
|
PARAM_DEFAULT(BoolUserConfigParam(true, "lobby-chat",
|
||||||
&m_network_group, "Enable chatting in networking lobby, if off than "
|
&m_network_group, "Enable chatting in networking lobby, if off than "
|
||||||
"no chat message will be displayed from any players."));
|
"no chat message will be displayed from any players."));
|
||||||
PARAM_PREFIX IntUserConfigParam m_max_players
|
PARAM_PREFIX IntUserConfigParam m_max_players
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "config/user_config.hpp"
|
#include "config/user_config.hpp"
|
||||||
|
#include "graphics/central_settings.hpp"
|
||||||
#include "graphics/material.hpp"
|
#include "graphics/material.hpp"
|
||||||
#include "graphics/particle_kind_manager.hpp"
|
#include "graphics/particle_kind_manager.hpp"
|
||||||
#include "graphics/sp/sp_texture_manager.hpp"
|
#include "graphics/sp/sp_texture_manager.hpp"
|
||||||
@ -57,9 +58,10 @@ MaterialManager::MaterialManager()
|
|||||||
MaterialManager::~MaterialManager()
|
MaterialManager::~MaterialManager()
|
||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
SP::SPTextureManager::get()->stopThreads();
|
if (CVS->isGLSL())
|
||||||
|
SP::SPTextureManager::get()->stopThreads();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(unsigned int i=0; i<m_materials.size(); i++)
|
for(unsigned int i=0; i<m_materials.size(); i++)
|
||||||
{
|
{
|
||||||
delete m_materials[i];
|
delete m_materials[i];
|
||||||
|
@ -272,7 +272,9 @@ PlayerKartWidget::~PlayerKartWidget()
|
|||||||
|
|
||||||
if (m_kart_name->getIrrlichtElement() != NULL)
|
if (m_kart_name->getIrrlichtElement() != NULL)
|
||||||
m_kart_name->getIrrlichtElement()->remove();
|
m_kart_name->getIrrlichtElement()->remove();
|
||||||
getCurrentScreen()->manualRemoveWidget(this);
|
|
||||||
|
if (getCurrentScreen() != NULL)
|
||||||
|
getCurrentScreen()->manualRemoveWidget(this);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
m_magic_number = 0xDEADBEEF;
|
m_magic_number = 0xDEADBEEF;
|
||||||
|
@ -631,3 +631,26 @@ std::string AssetsAndroid::getDataPath()
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Get a path for internal lib directory
|
||||||
|
* \return Path for internal lib directory or empty string when failed
|
||||||
|
*/
|
||||||
|
std::string AssetsAndroid::getLibPath()
|
||||||
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
AndroidApplicationInfo application_info =
|
||||||
|
CIrrDeviceAndroid::getApplicationInfo(global_android_app->activity);
|
||||||
|
|
||||||
|
std::string lib_path = application_info.native_lib_dir;
|
||||||
|
|
||||||
|
if (access(lib_path.c_str(), R_OK) != 0)
|
||||||
|
{
|
||||||
|
lib_path = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return lib_path;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
@ -43,6 +43,7 @@ public:
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
static std::string getDataPath();
|
static std::string getDataPath();
|
||||||
|
static std::string getLibPath();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,7 +110,8 @@ Attachment::~Attachment()
|
|||||||
*/
|
*/
|
||||||
void Attachment::set(AttachmentType type, int ticks,
|
void Attachment::set(AttachmentType type, int ticks,
|
||||||
AbstractKart *current_kart,
|
AbstractKart *current_kart,
|
||||||
bool disable_swatter_animation)
|
bool disable_swatter_animation,
|
||||||
|
bool set_by_rewind_parachute)
|
||||||
{
|
{
|
||||||
// Don't override currently player swatter removing bomb animation
|
// Don't override currently player swatter removing bomb animation
|
||||||
Swatter* s = dynamic_cast<Swatter*>(m_plugin);
|
Swatter* s = dynamic_cast<Swatter*>(m_plugin);
|
||||||
@ -179,7 +180,8 @@ void Attachment::set(AttachmentType type, int ticks,
|
|||||||
// A parachute can be attached as result of the usage of an item. In this
|
// A parachute can be attached as result of the usage of an item. In this
|
||||||
// case we have to save the current kart speed so that it can be detached
|
// case we have to save the current kart speed so that it can be detached
|
||||||
// by slowing down.
|
// by slowing down.
|
||||||
if(m_type==ATTACH_PARACHUTE)
|
// if set by rewind the parachute ticks is already correct
|
||||||
|
if (m_type == ATTACH_PARACHUTE && !set_by_rewind_parachute)
|
||||||
{
|
{
|
||||||
const KartProperties *kp = m_kart->getKartProperties();
|
const KartProperties *kp = m_kart->getKartProperties();
|
||||||
float speed_mult;
|
float speed_mult;
|
||||||
@ -306,19 +308,16 @@ void Attachment::rewindTo(BareNetworkString *buffer)
|
|||||||
|
|
||||||
// Attaching an object can be expensive (loading new models, ...)
|
// Attaching an object can be expensive (loading new models, ...)
|
||||||
// so avoid doing this if there is no change in attachment type
|
// so avoid doing this if there is no change in attachment type
|
||||||
// Don't use set to reset a model on local player if it's already cleared
|
if (m_type == new_type)
|
||||||
// (or m_initial_speed is redone / model is re-shown again when rewinding)
|
|
||||||
if (m_type == new_type || m_type == ATTACH_NOTHING)
|
|
||||||
{
|
{
|
||||||
setTicksLeft(ticks_left);
|
setTicksLeft(ticks_left);
|
||||||
if (m_type != new_type && new_type != ATTACH_SWATTER)
|
|
||||||
m_type = new_type;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(new_type, ticks_left, m_previous_owner,
|
set(new_type, ticks_left, m_previous_owner,
|
||||||
new_type == ATTACH_SWATTER && !is_removing_bomb
|
new_type == ATTACH_SWATTER && !is_removing_bomb
|
||||||
/*disable_swatter_animation*/);
|
/*disable_swatter_animation*/,
|
||||||
|
new_type == ATTACH_PARACHUTE);
|
||||||
} // rewindTo
|
} // rewindTo
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -353,6 +352,12 @@ void Attachment::hitBanana(ItemState *item_state)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make it consistent with attachment rewind when eating banana with bomb
|
||||||
|
// see if (m_type == ATTACH_BOMB && m_kart->getKartAnimation() != NULL)
|
||||||
|
// in 515
|
||||||
|
if (m_kart->getKartAnimation())
|
||||||
|
return;
|
||||||
|
|
||||||
AttachmentType new_attachment = ATTACH_NOTHING;
|
AttachmentType new_attachment = ATTACH_NOTHING;
|
||||||
const KartProperties *kp = m_kart->getKartProperties();
|
const KartProperties *kp = m_kart->getKartProperties();
|
||||||
// Use this as a basic random number to make sync with server easier.
|
// Use this as a basic random number to make sync with server easier.
|
||||||
@ -529,13 +534,19 @@ void Attachment::update(int ticks)
|
|||||||
m_node->setVisible((division & 0x1) == 0);
|
m_node->setVisible((division & 0x1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_plugin)
|
if (m_plugin)
|
||||||
{
|
{
|
||||||
bool discard = m_plugin->updateAndTestFinished(ticks);
|
int discard_ticks = m_plugin->updateAndTestFinished(ticks);
|
||||||
if(discard)
|
if (discard_ticks != -1)
|
||||||
{
|
{
|
||||||
clear(); // also removes the plugin
|
// Save it for rewinding
|
||||||
return;
|
m_ticks_left =
|
||||||
|
discard_ticks - World::getWorld()->getTicksSinceStart();
|
||||||
|
if (m_ticks_left <= 0)
|
||||||
|
{
|
||||||
|
clear(); // also removes the plugin
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,8 @@ public:
|
|||||||
void handleCollisionWithKart(AbstractKart *other);
|
void handleCollisionWithKart(AbstractKart *other);
|
||||||
void set (AttachmentType type, int ticks,
|
void set (AttachmentType type, int ticks,
|
||||||
AbstractKart *previous_kart=NULL,
|
AbstractKart *previous_kart=NULL,
|
||||||
bool disable_swatter_animation = false);
|
bool disable_swatter_animation = false,
|
||||||
|
bool set_by_rewind_parachute = false);
|
||||||
void rewindTo(BareNetworkString *buffer);
|
void rewindTo(BareNetworkString *buffer);
|
||||||
void saveState(BareNetworkString *buffer) const;
|
void saveState(BareNetworkString *buffer) const;
|
||||||
|
|
||||||
|
@ -53,8 +53,9 @@ public:
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Updates a plugin. This is called once each time frame. If the
|
/** Updates a plugin. This is called once each time frame. If the
|
||||||
* function returns true, the attachment is discarded. */
|
* function returns a non-negative number, the attachment is discarded
|
||||||
virtual bool updateAndTestFinished(int ticks) = 0;
|
* when world ticks >= that number. */
|
||||||
|
virtual int updateAndTestFinished(int ticks) = 0;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Called when the animation of the Attachment's node is done. */
|
/** Called when the animation of the Attachment's node is done. */
|
||||||
|
@ -224,6 +224,10 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the type of flyable. */
|
/** Returns the type of flyable. */
|
||||||
PowerupManager::PowerupType getType() const {return m_type;}
|
PowerupManager::PowerupType getType() const {return m_type;}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns the owner's kart */
|
||||||
|
AbstractKart *getOwner() const { return m_owner;}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the owner's kart */
|
/** Returns the owner's kart */
|
||||||
AbstractKart *getOwner() const { return m_owner;}
|
AbstractKart *getOwner() const { return m_owner;}
|
||||||
|
@ -37,6 +37,25 @@
|
|||||||
#include <ISceneManager.h>
|
#include <ISceneManager.h>
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Constructor.
|
||||||
|
* \param type Type of the item.
|
||||||
|
* \param owner If not NULL it is the kart that dropped this item; NULL
|
||||||
|
* indicates an item that's part of the track.
|
||||||
|
* \param id Index of this item in the array of all items.
|
||||||
|
*/
|
||||||
|
ItemState::ItemState(ItemType type, const AbstractKart *owner, int id)
|
||||||
|
{
|
||||||
|
setType(type);
|
||||||
|
m_item_id = id;
|
||||||
|
m_previous_owner = owner;
|
||||||
|
m_used_up_counter = -1;
|
||||||
|
if (owner)
|
||||||
|
setDeactivatedTicks(stk_config->time2Ticks(1.5f));
|
||||||
|
else
|
||||||
|
setDeactivatedTicks(0);
|
||||||
|
} // ItemState(ItemType)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Sets the disappear counter depending on type. */
|
/** Sets the disappear counter depending on type. */
|
||||||
void ItemState::setDisappearCounter()
|
void ItemState::setDisappearCounter()
|
||||||
@ -52,9 +71,23 @@ void ItemState::setDisappearCounter()
|
|||||||
} // switch
|
} // switch
|
||||||
} // setDisappearCounter
|
} // setDisappearCounter
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
/** Initialises an item.
|
||||||
|
* \param type Type for this item.
|
||||||
|
*/
|
||||||
|
void ItemState::initItem(ItemType type, const Vec3& xyz)
|
||||||
|
{
|
||||||
|
m_xyz = xyz;
|
||||||
|
m_original_type = ITEM_NONE;
|
||||||
|
m_ticks_till_return = 0;
|
||||||
|
setDisappearCounter();
|
||||||
|
} // initItem
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Update the state of the item, called once per physics frame.
|
/** Update the state of the item, called once per physics frame.
|
||||||
* \param ticks Number of ticks to simulate (typically 1).
|
* \param ticks Number of ticks to simulate. While this value is 1 when
|
||||||
|
* called during the normal game loop, during a rewind this value
|
||||||
|
* can be (much) larger than 1.
|
||||||
*/
|
*/
|
||||||
void ItemState::update(int ticks)
|
void ItemState::update(int ticks)
|
||||||
{
|
{
|
||||||
@ -107,12 +140,17 @@ void ItemState::collected(const AbstractKart *kart)
|
|||||||
* \param normal The normal upon which the item is placed (so that it can
|
* \param normal The normal upon which the item is placed (so that it can
|
||||||
* be aligned properly with the ground).
|
* be aligned properly with the ground).
|
||||||
* \param mesh The mesh to be used for this item.
|
* \param mesh The mesh to be used for this item.
|
||||||
|
* \param owner 'Owner' of this item, i.e. the kart that drops it. This is
|
||||||
|
* used to deactivate this item for the owner, i.e. avoid that a kart
|
||||||
|
* 'collects' its own bubble gum. NULL means no owner, and the item
|
||||||
|
* can be collected immediatley by any kart.
|
||||||
* \param is_predicted True if the creation of the item is predicted by
|
* \param is_predicted True if the creation of the item is predicted by
|
||||||
* a client. Only used in networking.
|
* a client. Only used in networking.
|
||||||
*/
|
*/
|
||||||
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||||
scene::IMesh* mesh, scene::IMesh* lowres_mesh, bool is_predicted)
|
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
|
||||||
: ItemState(type)
|
const AbstractKart *owner, bool is_predicted)
|
||||||
|
: ItemState(type, owner)
|
||||||
{
|
{
|
||||||
assert(type != ITEM_TRIGGER); // use other constructor for that
|
assert(type != ITEM_TRIGGER); // use other constructor for that
|
||||||
|
|
||||||
@ -190,7 +228,6 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
|
|||||||
void Item::initItem(ItemType type, const Vec3 &xyz)
|
void Item::initItem(ItemType type, const Vec3 &xyz)
|
||||||
{
|
{
|
||||||
ItemState::initItem(type, xyz);
|
ItemState::initItem(type, xyz);
|
||||||
m_previous_owner = NULL;
|
|
||||||
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
|
m_rotate = (getType()!=ITEM_BUBBLEGUM) &&
|
||||||
(getType()!=ITEM_TRIGGER );
|
(getType()!=ITEM_TRIGGER );
|
||||||
// Now determine in which quad this item is, and its distance
|
// Now determine in which quad this item is, and its distance
|
||||||
@ -334,17 +371,6 @@ void Item::reset()
|
|||||||
}
|
}
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** Sets which karts dropped an item. This is used to avoid that a kart is
|
|
||||||
* affected by its own items.
|
|
||||||
* \param parent Kart that dropped the item.
|
|
||||||
*/
|
|
||||||
void Item::setParent(const AbstractKart* parent)
|
|
||||||
{
|
|
||||||
m_previous_owner = parent;
|
|
||||||
ItemState::setDeactivatedTicks(stk_config->time2Ticks(1.5f));
|
|
||||||
} // setParent
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Updated the item - rotates it, takes care of items coming back into
|
/** Updated the item - rotates it, takes care of items coming back into
|
||||||
* the game after it has been collected.
|
* the game after it has been collected.
|
||||||
|
@ -122,35 +122,25 @@ private:
|
|||||||
* and then converting this value to a Vec3. */
|
* and then converting this value to a Vec3. */
|
||||||
Vec3 m_xyz;
|
Vec3 m_xyz;
|
||||||
|
|
||||||
protected:
|
|
||||||
/** The 'owner' of the item, i.e. the kart that dropped this item.
|
/** The 'owner' of the item, i.e. the kart that dropped this item.
|
||||||
* Is NULL if the item is part of the track. */
|
* Is NULL if the item is part of the track. */
|
||||||
const AbstractKart *m_previous_owner;
|
const AbstractKart *m_previous_owner;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
friend class ItemManager;
|
friend class ItemManager;
|
||||||
friend class NetworkItemManager;
|
friend class NetworkItemManager;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void setType(ItemType type) { m_type = type; }
|
virtual void setType(ItemType type) { m_type = type; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor.
|
ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1);
|
||||||
* \param type Type of the item.
|
void initItem(ItemType type, const Vec3& xyz);
|
||||||
* \param id Index of this item in the array of all items.
|
void update(int ticks);
|
||||||
* \param kart_id If !=-1 the kart that dropped this item; -1
|
void setDisappearCounter();
|
||||||
* indicates an item that's part of the track. */
|
virtual void collected(const AbstractKart *kart);
|
||||||
ItemState(ItemType type, int id=-1, AbstractKart *kart=NULL)
|
|
||||||
{
|
|
||||||
setType(type);
|
|
||||||
m_item_id = id;
|
|
||||||
m_previous_owner = kart;
|
|
||||||
} // ItemState(ItemType)
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual ~ItemState() {}
|
virtual ~ItemState() {}
|
||||||
void setDisappearCounter();
|
|
||||||
void update(int ticks);
|
|
||||||
virtual void collected(const AbstractKart *kart);
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
void reset()
|
void reset()
|
||||||
@ -166,19 +156,6 @@ public:
|
|||||||
}
|
}
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
/** Initialises an item.
|
|
||||||
* \param type Type for this item.
|
|
||||||
*/
|
|
||||||
void initItem(ItemType type, const Vec3& xyz)
|
|
||||||
{
|
|
||||||
m_xyz = xyz;
|
|
||||||
m_original_type = ITEM_NONE;
|
|
||||||
m_deactive_ticks = 0;
|
|
||||||
m_ticks_till_return = 0;
|
|
||||||
setDisappearCounter();
|
|
||||||
} // initItem
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Switches an item to be of a different type. Used for the switch
|
/** Switches an item to be of a different type. Used for the switch
|
||||||
* powerup.
|
* powerup.
|
||||||
@ -329,20 +306,19 @@ private:
|
|||||||
public:
|
public:
|
||||||
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||||
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
|
scene::IMesh* mesh, scene::IMesh* lowres_mesh,
|
||||||
|
const AbstractKart *owner,
|
||||||
bool is_predicted=false);
|
bool is_predicted=false);
|
||||||
Item(const Vec3& xyz, float distance,
|
Item(const Vec3& xyz, float distance,
|
||||||
TriggerItemListener* trigger);
|
TriggerItemListener* trigger);
|
||||||
virtual ~Item ();
|
virtual ~Item ();
|
||||||
void updateGraphics(float dt);
|
void updateGraphics(float dt);
|
||||||
virtual void collected(const AbstractKart *kart) OVERRIDE;
|
virtual void collected(const AbstractKart *kart) OVERRIDE;
|
||||||
void setParent(const AbstractKart* parent);
|
|
||||||
void reset();
|
void reset();
|
||||||
void switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh);
|
void switchTo(ItemType type, scene::IMesh *mesh,
|
||||||
|
scene::IMesh *lowmesh);
|
||||||
void switchBack();
|
void switchBack();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
/** Returns true if the Kart is close enough to hit this item, the item is
|
/** 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
|
* not deactivated anymore, and it wasn't placed by this kart (this is
|
||||||
* e.g. used to avoid that a kart hits a bubble gum it just dropped).
|
* e.g. used to avoid that a kart hits a bubble gum it just dropped).
|
||||||
@ -352,7 +328,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
|
bool hitKart(const Vec3 &xyz, const AbstractKart *kart=NULL) const
|
||||||
{
|
{
|
||||||
if (m_previous_owner == kart && getDeactivatedTicks() > 0)
|
if (getPreviousOwner() == kart && getDeactivatedTicks() > 0)
|
||||||
return false;
|
return false;
|
||||||
Vec3 lc = quatRotate(m_original_rotation, xyz - getXYZ());
|
Vec3 lc = quatRotate(m_original_rotation, xyz - getXYZ());
|
||||||
// Don't be too strict if the kart is a bit above the item
|
// Don't be too strict if the kart is a bit above the item
|
||||||
@ -373,7 +349,8 @@ protected:
|
|||||||
bool hitLine(const core::line3df &line,
|
bool hitLine(const core::line3df &line,
|
||||||
const AbstractKart *kart=NULL) const
|
const AbstractKart *kart=NULL) const
|
||||||
{
|
{
|
||||||
if (m_previous_owner == kart && getDeactivatedTicks() >0) return false;
|
if (getPreviousOwner() == kart && getDeactivatedTicks() > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
Vec3 closest = line.getClosestPoint(getXYZ().toIrrVector());
|
Vec3 closest = line.getClosestPoint(getXYZ().toIrrVector());
|
||||||
return hitKart(closest, kart);
|
return hitKart(closest, kart);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
||||||
{
|
{
|
||||||
|
m_ticks_till_return = 0;
|
||||||
m_type = (EventType)buffer->getUInt8();
|
m_type = (EventType)buffer->getUInt8();
|
||||||
m_ticks = buffer->getTime();
|
m_ticks = buffer->getTime();
|
||||||
m_kart_id = buffer->getInt8();
|
m_kart_id = buffer->getInt8();
|
||||||
@ -41,7 +42,11 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
|||||||
m_xyz = buffer->getVec3();
|
m_xyz = buffer->getVec3();
|
||||||
*count -= 12;
|
*count -= 12;
|
||||||
}
|
}
|
||||||
|
else if (m_type == IEI_COLLECT)
|
||||||
|
{
|
||||||
|
m_ticks_till_return = buffer->getUInt16();
|
||||||
|
*count -= 2;
|
||||||
|
}
|
||||||
} // ItemEventInfo(BareNetworkString, int *count)
|
} // ItemEventInfo(BareNetworkString, int *count)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -55,7 +60,6 @@ void ItemEventInfo::saveState(BareNetworkString *buffer)
|
|||||||
.addUInt16(m_index);
|
.addUInt16(m_index);
|
||||||
if(m_type == IEI_NEW)
|
if(m_type == IEI_NEW)
|
||||||
buffer->add(m_xyz);
|
buffer->add(m_xyz);
|
||||||
|
else if (m_type == IEI_COLLECT)
|
||||||
|
buffer->addUInt16(m_ticks_till_return);
|
||||||
} // saveState
|
} // saveState
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "items/item.hpp"
|
#include "items/item.hpp"
|
||||||
#include "utils/vec3.hpp"
|
#include "utils/vec3.hpp"
|
||||||
|
#include "utils/types.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@ -51,13 +52,20 @@ private:
|
|||||||
/** In case of new items the position of the new item. */
|
/** In case of new items the position of the new item. */
|
||||||
Vec3 m_xyz;
|
Vec3 m_xyz;
|
||||||
|
|
||||||
|
/** Ticks for the item to return, atm used by collecting banana
|
||||||
|
* with bomb to delay the return for banana. */
|
||||||
|
int16_t m_ticks_till_return;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor for collecting an existing item.
|
/** Constructor for collecting an existing item.
|
||||||
* \param ticks Time of the event.
|
* \param ticks Time of the event.
|
||||||
* \param item_id The index of the item that was collected.
|
* \param item_id The index of the item that was collected.
|
||||||
* \param kart_id the kart that collected the item. */
|
* \param kart_id the kart that collected the item.
|
||||||
ItemEventInfo(int ticks, int index, int kart_id)
|
* \param ttr Ticks till return after being collected. */
|
||||||
: m_ticks(ticks), m_index(index), m_kart_id(kart_id)
|
|
||||||
|
ItemEventInfo(int ticks, int index, int kart_id, int16_t ttr)
|
||||||
|
: m_ticks(ticks), m_index(index), m_kart_id(kart_id),
|
||||||
|
m_ticks_till_return(ttr)
|
||||||
{
|
{
|
||||||
m_type = IEI_COLLECT;
|
m_type = IEI_COLLECT;
|
||||||
} // ItemEventInfo(collected existing item)
|
} // ItemEventInfo(collected existing item)
|
||||||
@ -69,14 +77,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
ItemEventInfo(int ticks, ItemState::ItemType type, int index,
|
ItemEventInfo(int ticks, ItemState::ItemType type, int index,
|
||||||
int kart_id, const Vec3 &xyz)
|
int kart_id, const Vec3 &xyz)
|
||||||
: m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz)
|
: m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz),
|
||||||
|
m_ticks_till_return(0)
|
||||||
{
|
{
|
||||||
m_type = IEI_NEW;
|
m_type = IEI_NEW;
|
||||||
} // ItemEventInfo(new item)
|
} // ItemEventInfo(new item)
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** Constructor for switching items. */
|
/** Constructor for switching items. */
|
||||||
ItemEventInfo(int ticks) : m_ticks(ticks)
|
ItemEventInfo(int ticks) : m_ticks(ticks), m_ticks_till_return(0)
|
||||||
{
|
{
|
||||||
m_type = IEI_SWITCH;
|
m_type = IEI_SWITCH;
|
||||||
} // ItemEventInfo(switch)
|
} // ItemEventInfo(switch)
|
||||||
@ -116,6 +125,9 @@ public:
|
|||||||
return m_xyz;
|
return m_xyz;
|
||||||
} // getXYZ
|
} // getXYZ
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
/** Returns the ticks till return, used only by collection events. */
|
||||||
|
int getTicksTillReturn() const { return m_ticks_till_return; }
|
||||||
|
// --------------------------------------------------------------------
|
||||||
/** Returns the type of this item. Note at this stage only bubble gums
|
/** Returns the type of this item. Note at this stage only bubble gums
|
||||||
* can be created during a race. */
|
* can be created during a race. */
|
||||||
ItemState::ItemType getNewItemType() const
|
ItemState::ItemType getNewItemType() const
|
||||||
|
@ -226,13 +226,15 @@ unsigned int ItemManager::insertItem(Item *item)
|
|||||||
// previously deleted entry, otherwise at the end.
|
// previously deleted entry, otherwise at the end.
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for(index=(int)m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
for(index=(int)m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
||||||
|
if (index == -1)
|
||||||
if(index==-1) index = (int)m_all_items.size();
|
{
|
||||||
|
index = (int)m_all_items.size();
|
||||||
if(index<(int)m_all_items.size())
|
|
||||||
m_all_items[index] = item;
|
|
||||||
else
|
|
||||||
m_all_items.push_back(item);
|
m_all_items.push_back(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_all_items[index] = item;
|
||||||
|
}
|
||||||
item->setItemId(index);
|
item->setItemId(index);
|
||||||
|
|
||||||
// Now insert into the appropriate quad list, if there is a quad list
|
// Now insert into the appropriate quad list, if there is a quad list
|
||||||
@ -286,9 +288,7 @@ Item* ItemManager::dropNewItem(ItemState::ItemType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
Item* item = new Item(type, pos, normal, m_item_mesh[mesh_type],
|
||||||
m_item_lowres_mesh[mesh_type]);
|
m_item_lowres_mesh[mesh_type], /*prev_owner*/kart);
|
||||||
|
|
||||||
if(kart != NULL) item->setParent(kart);
|
|
||||||
insertItem(item);
|
insertItem(item);
|
||||||
if(m_switch_ticks>=0)
|
if(m_switch_ticks>=0)
|
||||||
{
|
{
|
||||||
@ -318,7 +318,7 @@ Item* ItemManager::placeItem(ItemState::ItemType type, const Vec3& xyz,
|
|||||||
ItemState::ItemType mesh_type = type;
|
ItemState::ItemType mesh_type = type;
|
||||||
|
|
||||||
Item* item = new Item(type, xyz, normal, m_item_mesh[mesh_type],
|
Item* item = new Item(type, xyz, normal, m_item_mesh[mesh_type],
|
||||||
m_item_lowres_mesh[mesh_type]);
|
m_item_lowres_mesh[mesh_type], /*prev_owner*/NULL);
|
||||||
|
|
||||||
insertItem(item);
|
insertItem(item);
|
||||||
if (m_switch_ticks >= 0)
|
if (m_switch_ticks >= 0)
|
||||||
@ -354,7 +354,7 @@ Item* ItemManager::placeTrigger(const Vec3& xyz, float distance,
|
|||||||
* \param item The item that was collected.
|
* \param item The item that was collected.
|
||||||
* \param kart The kart that collected the item.
|
* \param kart The kart that collected the item.
|
||||||
*/
|
*/
|
||||||
void ItemManager::collectedItem(Item *item, AbstractKart *kart)
|
void ItemManager::collectedItem(ItemState *item, AbstractKart *kart)
|
||||||
{
|
{
|
||||||
assert(item);
|
assert(item);
|
||||||
// Spare tire karts don't collect items
|
// Spare tire karts don't collect items
|
||||||
|
@ -133,7 +133,7 @@ public:
|
|||||||
void updateGraphics (float dt);
|
void updateGraphics (float dt);
|
||||||
void checkItemHit (AbstractKart* kart);
|
void checkItemHit (AbstractKart* kart);
|
||||||
void reset ();
|
void reset ();
|
||||||
virtual void collectedItem (Item *item, AbstractKart *kart);
|
virtual void collectedItem (ItemState *item, AbstractKart *kart);
|
||||||
void switchItems ();
|
void switchItems ();
|
||||||
bool areItemSwitched() { return (m_switch_ticks > 0); }
|
bool areItemSwitched() { return (m_switch_ticks > 0); }
|
||||||
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
|
bool randomItemsForArena(const AlignedArray<btTransform>& pos);
|
||||||
|
@ -95,17 +95,18 @@ void NetworkItemManager::initClientConfirmState()
|
|||||||
* \param item The item that was collected.
|
* \param item The item that was collected.
|
||||||
* \param kart The kart that collected the item.
|
* \param kart The kart that collected the item.
|
||||||
*/
|
*/
|
||||||
void NetworkItemManager::collectedItem(Item *item, AbstractKart *kart)
|
void NetworkItemManager::collectedItem(ItemState *item, AbstractKart *kart)
|
||||||
{
|
{
|
||||||
if(NetworkConfig::get()->isServer())
|
if(NetworkConfig::get()->isServer())
|
||||||
{
|
{
|
||||||
|
ItemManager::collectedItem(item, kart);
|
||||||
// The server saves the collected item as item event info
|
// The server saves the collected item as item event info
|
||||||
m_item_events.lock();
|
m_item_events.lock();
|
||||||
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
||||||
item->getItemId(),
|
item->getItemId(),
|
||||||
kart->getWorldKartId());
|
kart->getWorldKartId(),
|
||||||
|
item->getTicksTillReturn());
|
||||||
m_item_events.unlock();
|
m_item_events.unlock();
|
||||||
ItemManager::collectedItem(item, kart);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -142,7 +143,7 @@ Item* NetworkItemManager::dropNewItem(ItemState::ItemType type,
|
|||||||
kart->getXYZ() );
|
kart->getXYZ() );
|
||||||
m_item_events.unlock();
|
m_item_events.unlock();
|
||||||
return item;
|
return item;
|
||||||
} // newItem
|
} // dropNewItem
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Called by the GameProtocol when a confirmation for an item event is
|
/** Called by the GameProtocol when a confirmation for an item event is
|
||||||
@ -237,9 +238,9 @@ void NetworkItemManager::forwardTime(int ticks)
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Restores the state of the items to the current world time. It takes the
|
/** Restores the state of the items to the current world time. It takes the
|
||||||
* last saved
|
* last saved confirmed state, applies any updates from the server, and
|
||||||
|
* then syncs up the confirmed state to the in-race items.
|
||||||
* using exactly 'count' bytes of the message.
|
* It uses exactly 'count' bytes of the message.
|
||||||
* \param buffer the state content.
|
* \param buffer the state content.
|
||||||
* \param count Number of bytes used for this state.
|
* \param count Number of bytes used for this state.
|
||||||
*/
|
*/
|
||||||
@ -267,6 +268,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// From here the replay can happen.
|
// From here the replay can happen.
|
||||||
|
|
||||||
// 1) Remove predicted items:
|
// 1) Remove predicted items:
|
||||||
|
// --------------------------
|
||||||
for (unsigned int i=0; i<m_all_items.size(); i++)
|
for (unsigned int i=0; i<m_all_items.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = m_all_items[i];
|
Item *item = m_all_items[i];
|
||||||
@ -274,20 +276,22 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
{
|
{
|
||||||
deleteItem(item);
|
deleteItem(item);
|
||||||
}
|
}
|
||||||
}
|
} // for i in m_all_items
|
||||||
|
|
||||||
// 2) Apply all events to current confirmed state:
|
// 2) Apply all events to current confirmed state:
|
||||||
|
// -----------------------------------------------
|
||||||
|
World *world = World::getWorld();
|
||||||
int current_time = m_confirmed_state_time;
|
int current_time = m_confirmed_state_time;
|
||||||
bool has_state = count > 0;
|
bool has_state = count > 0;
|
||||||
while(count > 0)
|
while(count > 0)
|
||||||
{
|
{
|
||||||
// 1) Decode the event in the message
|
// 2.1) Decode the event in the message
|
||||||
// ----------------------------------
|
// ------------------------------------
|
||||||
ItemEventInfo iei(buffer, &count);
|
ItemEventInfo iei(buffer, &count);
|
||||||
|
|
||||||
// 2) If the event needs to be applied, forward
|
// 2.2) If the event needs to be applied, forward
|
||||||
// the time to the time of this event:
|
// the time to the time of this event:
|
||||||
// --------------------------------------------
|
// ----------------------------------------------
|
||||||
int dt = iei.getTicks() - current_time;
|
int dt = iei.getTicks() - current_time;
|
||||||
// Skip an event that are 'in the past' (i.e. have been sent again by
|
// Skip an event that are 'in the past' (i.e. have been sent again by
|
||||||
// the server because it has not yet received confirmation from all
|
// the server because it has not yet received confirmation from all
|
||||||
@ -297,13 +301,35 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
// Forward the saved state:
|
// Forward the saved state:
|
||||||
if (dt>0) forwardTime(dt);
|
if (dt>0) forwardTime(dt);
|
||||||
|
|
||||||
// TODO: apply the various events types, atm only collection is supported:
|
// TODO: apply the various events types, atm only collection
|
||||||
|
// and new items are supported.
|
||||||
if(iei.isItemCollection())
|
if(iei.isItemCollection())
|
||||||
{
|
{
|
||||||
int index = iei.getIndex();
|
int index = iei.getIndex();
|
||||||
// An item on the track was collected:
|
// An item on the track was collected:
|
||||||
AbstractKart *kart = World::getWorld()->getKart(iei.getKartId());
|
AbstractKart *kart = world->getKart(iei.getKartId());
|
||||||
m_confirmed_state[index]->collected(kart);
|
|
||||||
|
// The world clock was set by the RewindManager to be the time
|
||||||
|
// of the state we are rewinding to. But this confirmed collection
|
||||||
|
// event happened in the past (we are replaying item events since
|
||||||
|
// the last confirmed state in order to get a new confirmed state).
|
||||||
|
// So we need to reset the clock to the time at which this event
|
||||||
|
// happened so that (e.g.) kart can use the right time (for
|
||||||
|
// example, bubble gum torque depends on time, and would be wrong
|
||||||
|
// otherwise resulting in stuttering).
|
||||||
|
int old_time = world->getTicksSinceStart(); // Save time we rewind to
|
||||||
|
world->setTicksForRewind(iei.getTicks()); // Set time of event
|
||||||
|
|
||||||
|
if (m_confirmed_state[index] != NULL)
|
||||||
|
{
|
||||||
|
m_confirmed_state[index]->collected(kart);// Collect item
|
||||||
|
// Reset till ticks return from state (required for eating banana with bomb)
|
||||||
|
int ttr = iei.getTicksTillReturn();
|
||||||
|
m_confirmed_state[index]->setTicksTillReturn(ttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
world->setTicksForRewind(old_time); // Set time to rewind-to
|
||||||
|
|
||||||
if (m_confirmed_state[index]->isUsedUp())
|
if (m_confirmed_state[index]->isUsedUp())
|
||||||
{
|
{
|
||||||
delete m_confirmed_state[index];
|
delete m_confirmed_state[index];
|
||||||
@ -312,9 +338,9 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
}
|
}
|
||||||
else if(iei.isNewItem())
|
else if(iei.isNewItem())
|
||||||
{
|
{
|
||||||
AbstractKart *kart = World::getWorld()->getKart(iei.getKartId());
|
AbstractKart *kart = world->getKart(iei.getKartId());
|
||||||
ItemState *is = new ItemState(iei.getNewItemType(), iei.getIndex(),
|
ItemState *is = new ItemState(iei.getNewItemType(), kart,
|
||||||
kart);
|
iei.getIndex() );
|
||||||
is->initItem(iei.getNewItemType(), iei.getXYZ());
|
is->initItem(iei.getNewItemType(), iei.getXYZ());
|
||||||
if (m_confirmed_state.size() <= is->getItemId())
|
if (m_confirmed_state.size() <= is->getItemId())
|
||||||
{
|
{
|
||||||
@ -325,29 +351,34 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
if (m_confirmed_state[is->getItemId()] == NULL)
|
if (m_confirmed_state[is->getItemId()] == NULL)
|
||||||
m_confirmed_state[is->getItemId()] = is;
|
m_confirmed_state[is->getItemId()] = is;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
*m_confirmed_state[is->getItemId()] = *is;
|
*m_confirmed_state[is->getItemId()] = *is;
|
||||||
|
delete is;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_time = iei.getTicks();
|
current_time = iei.getTicks();
|
||||||
} // while count >0
|
} // while count >0
|
||||||
|
|
||||||
// Inform the server which events have been received.
|
// Inform the server which events have been received (if there has
|
||||||
|
// been any updates - no need to send messages if nothing has changed)
|
||||||
|
|
||||||
if (has_state)
|
if (has_state)
|
||||||
{
|
{
|
||||||
if (auto gp = GameProtocol::lock())
|
if (auto gp = GameProtocol::lock())
|
||||||
gp->sendItemEventConfirmation(World::getWorld()->getTicksSinceStart());
|
gp->sendItemEventConfirmation(world->getTicksSinceStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward the confirmed item state to the world time:
|
// Forward the confirmed item state to the world time:
|
||||||
int dt = World::getWorld()->getTicksSinceStart() - current_time;
|
int dt = world->getTicksSinceStart() - current_time;
|
||||||
if(dt>0) forwardTime(dt);
|
if(dt>0) forwardTime(dt);
|
||||||
|
|
||||||
// Restore the state to the current world time:
|
// 3. Restore the state to the current world time:
|
||||||
// ============================================
|
// ===============================================
|
||||||
|
|
||||||
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
|
for(unsigned int i=0; i<m_confirmed_state.size(); i++)
|
||||||
{
|
{
|
||||||
Item *item = m_all_items[i];
|
Item *item = i < m_all_items.size() ? m_all_items[i] : NULL;
|
||||||
const ItemState *is = m_confirmed_state[i];
|
const ItemState *is = m_confirmed_state[i];
|
||||||
if (is && item)
|
if (is && item)
|
||||||
*(ItemState*)item = *is;
|
*(ItemState*)item = *is;
|
||||||
@ -356,18 +387,33 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
|||||||
Vec3 xyz = is->getXYZ();
|
Vec3 xyz = is->getXYZ();
|
||||||
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
||||||
&xyz);
|
&xyz);
|
||||||
|
if (i != item_new->getItemId())
|
||||||
|
{
|
||||||
|
// The server has this item at a different index in the list
|
||||||
|
// of all items, which means the client has an incorrect
|
||||||
|
// item at the index given by the server - delete that item
|
||||||
|
Log::info("nim", "about to delete item with not matching index i %d item %d",
|
||||||
|
i, item_new->getItemId());
|
||||||
|
if(m_all_items[i])
|
||||||
|
deleteItem(m_all_items[i]);
|
||||||
|
m_all_items[item_new->getItemId()] = NULL;
|
||||||
|
m_all_items[i] = item_new;
|
||||||
|
item_new->setItemId(i);
|
||||||
|
}
|
||||||
item_new->setPredicted(false);
|
item_new->setPredicted(false);
|
||||||
item_new->setItemId(i);
|
item_new->setDeactivatedTicks(is->getDeactivatedTicks());
|
||||||
m_all_items[i] = item_new;
|
|
||||||
*((ItemState*)m_all_items[i]) = *is;
|
*((ItemState*)m_all_items[i]) = *is;
|
||||||
}
|
}
|
||||||
else if (!is && item)
|
else if (!is && item)
|
||||||
{
|
{
|
||||||
|
Log::info("nim", "About to delete item index %d i %d",
|
||||||
|
item->getItemId(), i);
|
||||||
|
|
||||||
deleteItem(m_all_items[i]);
|
deleteItem(m_all_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we save the current local
|
// Now we save the current local
|
||||||
m_confirmed_state_time = World::getWorld()->getTicksSinceStart();
|
m_confirmed_state_time = world->getTicksSinceStart();
|
||||||
} // restoreState
|
} // restoreState
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
virtual void reset() OVERRIDE;
|
virtual void reset() OVERRIDE;
|
||||||
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
virtual void setItemConfirmationTime(std::weak_ptr<STKPeer> peer,
|
||||||
int ticks) OVERRIDE;
|
int ticks) OVERRIDE;
|
||||||
virtual void collectedItem(Item *item, AbstractKart *kart) OVERRIDE;
|
virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE;
|
||||||
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
||||||
const Vec3 *xyz=NULL) OVERRIDE;
|
const Vec3 *xyz=NULL) OVERRIDE;
|
||||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||||
|
@ -256,7 +256,7 @@ BareNetworkString* Plunger::saveState(std::vector<std::string>* ru)
|
|||||||
BareNetworkString* buffer = Flyable::saveState(ru);
|
BareNetworkString* buffer = Flyable::saveState(ru);
|
||||||
buffer->addUInt16(m_keep_alive).addUInt8(m_moved_to_infinity ? 1 : 0);
|
buffer->addUInt16(m_keep_alive).addUInt8(m_moved_to_infinity ? 1 : 0);
|
||||||
if (m_rubber_band)
|
if (m_rubber_band)
|
||||||
buffer->addUInt8(m_rubber_band->getRubberBandTo());
|
buffer->addUInt8(m_rubber_band->get8BitState());
|
||||||
else
|
else
|
||||||
buffer->addUInt8(255);
|
buffer->addUInt8(255);
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -268,7 +268,20 @@ void Plunger::restoreState(BareNetworkString *buffer, int count)
|
|||||||
Flyable::restoreState(buffer, count);
|
Flyable::restoreState(buffer, count);
|
||||||
m_keep_alive = buffer->getUInt16();
|
m_keep_alive = buffer->getUInt16();
|
||||||
m_moved_to_infinity = buffer->getUInt8() == 1;
|
m_moved_to_infinity = buffer->getUInt8() == 1;
|
||||||
int8_t rbt = buffer->getUInt8();
|
uint8_t bit_state = buffer->getUInt8();
|
||||||
if (rbt != -1 && m_rubber_band)
|
if (bit_state == 255 && m_rubber_band)
|
||||||
m_rubber_band->setRubberBandTo((RubberBand::RubberBandTo)rbt);
|
{
|
||||||
|
delete m_rubber_band;
|
||||||
|
m_rubber_band = NULL;
|
||||||
|
if (!m_reverse_mode)
|
||||||
|
m_reverse_mode = true;
|
||||||
|
}
|
||||||
|
else if (bit_state != 255 && !m_rubber_band)
|
||||||
|
{
|
||||||
|
m_rubber_band = new RubberBand(this, m_owner);
|
||||||
|
if (m_reverse_mode)
|
||||||
|
m_reverse_mode = false;
|
||||||
|
}
|
||||||
|
if (bit_state != 255)
|
||||||
|
m_rubber_band->set8BitState(bit_state);
|
||||||
} // restoreState
|
} // restoreState
|
||||||
|
@ -563,7 +563,7 @@ void Powerup::hitBonusBox(const ItemState &item_state)
|
|||||||
random_number);
|
random_number);
|
||||||
// FIXME Disable switch and bubblegum for now in network
|
// FIXME Disable switch and bubblegum for now in network
|
||||||
if (NetworkConfig::get()->isNetworking() &&
|
if (NetworkConfig::get()->isNetworking() &&
|
||||||
(new_powerup == PowerupManager::POWERUP_BUBBLEGUM ||
|
(new_powerup == PowerupManager::POWERUP_BUBBLEGUM ||
|
||||||
new_powerup == PowerupManager::POWERUP_SWITCH))
|
new_powerup == PowerupManager::POWERUP_SWITCH))
|
||||||
new_powerup = PowerupManager::POWERUP_BOWLING;
|
new_powerup = PowerupManager::POWERUP_BOWLING;
|
||||||
|
|
||||||
|
@ -314,3 +314,4 @@ std::shared_ptr<Rewinder>
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} // addProjectileFromNetworkState
|
} // addProjectileFromNetworkState
|
||||||
|
|
||||||
|
@ -101,3 +101,4 @@ extern ProjectileManager *projectile_manager;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||||
: m_plunger(plunger), m_owner(kart)
|
: m_plunger(plunger), m_owner(kart)
|
||||||
{
|
{
|
||||||
|
m_hit_kart = NULL;
|
||||||
m_attached_state = RB_TO_PLUNGER;
|
m_attached_state = RB_TO_PLUNGER;
|
||||||
updatePosition();
|
updatePosition();
|
||||||
|
|
||||||
@ -276,6 +277,7 @@ void RubberBand::hit(AbstractKart *kart_hit, const Vec3 *track_xyz)
|
|||||||
// =================
|
// =================
|
||||||
m_hit_position = *track_xyz;
|
m_hit_position = *track_xyz;
|
||||||
m_attached_state = RB_TO_TRACK;
|
m_attached_state = RB_TO_TRACK;
|
||||||
|
m_hit_kart = NULL;
|
||||||
} // hit
|
} // hit
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -289,3 +291,24 @@ void RubberBand::remove()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // remove
|
} // remove
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
uint8_t RubberBand::get8BitState() const
|
||||||
|
{
|
||||||
|
uint8_t state = (uint8_t)(m_attached_state & 3);
|
||||||
|
state |= m_attached_state == RB_TO_KART && m_hit_kart ?
|
||||||
|
(m_hit_kart->getWorldKartId() << 3) : 0;
|
||||||
|
return state;
|
||||||
|
} // get8BitState
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void RubberBand::set8BitState(uint8_t bit_state)
|
||||||
|
{
|
||||||
|
m_hit_kart = NULL;
|
||||||
|
m_attached_state = (RubberBandTo)(bit_state & 3);
|
||||||
|
if (m_attached_state == RB_TO_KART)
|
||||||
|
{
|
||||||
|
unsigned kart = bit_state >> 3;
|
||||||
|
m_hit_kart = World::getWorld()->getKart(kart);
|
||||||
|
}
|
||||||
|
} // set8BitState
|
||||||
|
@ -73,8 +73,8 @@ public:
|
|||||||
void updateGraphics(float dt);
|
void updateGraphics(float dt);
|
||||||
void update(int ticks);
|
void update(int ticks);
|
||||||
void hit(AbstractKart *kart_hit, const Vec3 *track_xyz=NULL);
|
void hit(AbstractKart *kart_hit, const Vec3 *track_xyz=NULL);
|
||||||
RubberBandTo getRubberBandTo() const { return m_attached_state; }
|
uint8_t get8BitState() const;
|
||||||
void setRubberBandTo(RubberBandTo rbt) { m_attached_state = rbt; }
|
void set8BitState(uint8_t bit_state);
|
||||||
void remove();
|
void remove();
|
||||||
}; // RubberBand
|
}; // RubberBand
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,20 +161,20 @@ void Swatter::updateGrahpics(float dt)
|
|||||||
/** Updates an armed swatter: it checks for any karts that are close enough
|
/** Updates an armed swatter: it checks for any karts that are close enough
|
||||||
* and not invulnerable, it swats the kart.
|
* and not invulnerable, it swats the kart.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
* \return True if the attachment should be discarded.
|
* \return World ticks to discard the swatter.
|
||||||
*/
|
*/
|
||||||
bool Swatter::updateAndTestFinished(int ticks)
|
int Swatter::updateAndTestFinished(int ticks)
|
||||||
{
|
{
|
||||||
const int ticks_start = World::getWorld()->getTicksSinceStart();
|
const int ticks_start = World::getWorld()->getTicksSinceStart();
|
||||||
if (m_removed_bomb_ticks != std::numeric_limits<int>::max())
|
if (m_removed_bomb_ticks != std::numeric_limits<int>::max())
|
||||||
{
|
{
|
||||||
if (ticks_start >= m_removed_bomb_ticks)
|
if (ticks_start >= m_removed_bomb_ticks)
|
||||||
return true;
|
return m_removed_bomb_ticks;
|
||||||
return false;
|
return -1;
|
||||||
} // if removing bomb
|
} // if removing bomb
|
||||||
|
|
||||||
if (RewindManager::get()->isRewinding())
|
if (RewindManager::get()->isRewinding())
|
||||||
return false;
|
return -1;
|
||||||
|
|
||||||
if (!m_discard_now)
|
if (!m_discard_now)
|
||||||
{
|
{
|
||||||
@ -186,7 +186,7 @@ bool Swatter::updateAndTestFinished(int ticks)
|
|||||||
// to make sure all clients know the existence of swatter each other
|
// to make sure all clients know the existence of swatter each other
|
||||||
if (ticks_start - m_swatter_start_ticks < 60 ||
|
if (ticks_start - m_swatter_start_ticks < 60 ||
|
||||||
m_swatter_end_ticks - ticks_start < 60)
|
m_swatter_end_ticks - ticks_start < 60)
|
||||||
return false;
|
return -1;
|
||||||
|
|
||||||
chooseTarget();
|
chooseTarget();
|
||||||
pointToTarget();
|
pointToTarget();
|
||||||
@ -258,15 +258,15 @@ bool Swatter::updateAndTestFinished(int ticks)
|
|||||||
|
|
||||||
if (m_discard_now)
|
if (m_discard_now)
|
||||||
{
|
{
|
||||||
return ticks_start > m_end_swat_ticks;
|
return m_end_swat_ticks;
|
||||||
}
|
}
|
||||||
else if (ticks_start > m_end_swat_ticks)
|
else if (ticks_start > m_end_swat_ticks)
|
||||||
{
|
{
|
||||||
m_animation_phase = SWATTER_AIMING;
|
m_animation_phase = SWATTER_AIMING;
|
||||||
m_end_swat_ticks = std::numeric_limits<int>::max();
|
m_end_swat_ticks = std::numeric_limits<int>::max();
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
return false;
|
return -1;
|
||||||
} // updateAndTestFinished
|
} // updateAndTestFinished
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -87,7 +87,7 @@ public:
|
|||||||
scene::ISceneNode* bomb_scene_node, int ticks);
|
scene::ISceneNode* bomb_scene_node, int ticks);
|
||||||
virtual ~Swatter();
|
virtual ~Swatter();
|
||||||
void updateGrahpics(float dt) OVERRIDE;
|
void updateGrahpics(float dt) OVERRIDE;
|
||||||
bool updateAndTestFinished(int ticks) OVERRIDE;
|
int updateAndTestFinished(int ticks) OVERRIDE;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns if the swatter is currently aiming, i.e. can be used to
|
/** Returns if the swatter is currently aiming, i.e. can be used to
|
||||||
|
@ -261,6 +261,8 @@ public:
|
|||||||
/** Returns true if the kart has a plunger attached to its face. */
|
/** Returns true if the kart has a plunger attached to its face. */
|
||||||
virtual int getBlockedByPlungerTicks() const = 0;
|
virtual int getBlockedByPlungerTicks() const = 0;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
virtual float getGraphicalViewBlockedByPlunger() const = 0;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Sets that the view is blocked by a plunger. The duration depends on
|
/** Sets that the view is blocked by a plunger. The duration depends on
|
||||||
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
||||||
virtual void blockViewWithPlunger() = 0;
|
virtual void blockViewWithPlunger() = 0;
|
||||||
|
@ -143,9 +143,19 @@ void AbstractKartAnimation::addNetworkAnimationChecker(bool reset_powerup)
|
|||||||
{
|
{
|
||||||
// Prevent access to deleted kart animation object
|
// Prevent access to deleted kart animation object
|
||||||
std::weak_ptr<int> cct = m_check_created_ticks;
|
std::weak_ptr<int> cct = m_check_created_ticks;
|
||||||
|
Vec3 original_position;
|
||||||
|
AbstractKart* k = m_kart;
|
||||||
|
if (k)
|
||||||
|
original_position = k->getXYZ();
|
||||||
RewindManager::get()->addRewindInfoEventFunction(new
|
RewindManager::get()->addRewindInfoEventFunction(new
|
||||||
RewindInfoEventFunction(m_created_ticks,
|
RewindInfoEventFunction(m_created_ticks,
|
||||||
[](){},
|
/*undo_function*/[cct, k, original_position]()
|
||||||
|
{
|
||||||
|
auto cct_sp = cct.lock();
|
||||||
|
if (!cct_sp || !k)
|
||||||
|
return;
|
||||||
|
k->setXYZ(original_position);
|
||||||
|
},
|
||||||
/*replay_function*/[p]()
|
/*replay_function*/[p]()
|
||||||
{
|
{
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -30,6 +30,14 @@
|
|||||||
|
|
||||||
class AbstractKart;
|
class AbstractKart;
|
||||||
|
|
||||||
|
enum KartAnimationType : uint8_t
|
||||||
|
{
|
||||||
|
KAT_RESCUE = 0,
|
||||||
|
KAT_EXPLOSION_DIRECT_HIT = 1,
|
||||||
|
KAT_EXPLOSION = 2,
|
||||||
|
KAT_CANNON = 3
|
||||||
|
};
|
||||||
|
|
||||||
/** The base class for all kart animation, like rescue, explosion, or cannon.
|
/** The base class for all kart animation, like rescue, explosion, or cannon.
|
||||||
* Kart animations are done by removing the physics body from the physics
|
* Kart animations are done by removing the physics body from the physics
|
||||||
* world, and instead modifying the rotation and position of the kart
|
* world, and instead modifying the rotation and position of the kart
|
||||||
@ -94,10 +102,12 @@ public:
|
|||||||
m_end_transform = t;
|
m_end_transform = t;
|
||||||
m_end_ticks = ticks;
|
m_end_ticks = ticks;
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void checkNetworkAnimationCreationSucceed(const btTransform& fallback_trans);
|
void checkNetworkAnimationCreationSucceed(const btTransform& fb_trans);
|
||||||
// ----------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
int getEndTicks() const { return m_end_ticks; }
|
int getEndTicks() const { return m_end_ticks; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual KartAnimationType getAnimationType() const = 0;
|
||||||
}; // AbstractKartAnimation
|
}; // AbstractKartAnimation
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,6 +81,8 @@ public:
|
|||||||
virtual ~CannonAnimation();
|
virtual ~CannonAnimation();
|
||||||
virtual void update(int ticks);
|
virtual void update(int ticks);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual bool usePredefinedEndTransform() const { return false; }
|
virtual bool usePredefinedEndTransform() const { return false; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual KartAnimationType getAnimationType() const { return KAT_CANNON; }
|
||||||
}; // CannonAnimation
|
}; // CannonAnimation
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,6 +101,8 @@ void NetworkAIController::convertAIToPlayerActions()
|
|||||||
0 : 32768);
|
0 : 32768);
|
||||||
all_actions.emplace_back(PA_RESCUE,
|
all_actions.emplace_back(PA_RESCUE,
|
||||||
m_ai_controls->getRescue() ? 32768 : 0);
|
m_ai_controls->getRescue() ? 32768 : 0);
|
||||||
|
all_actions.emplace_back(PA_LOOK_BACK,
|
||||||
|
m_ai_controls->getLookBack() ? 32768 : 0);
|
||||||
|
|
||||||
for (const auto& a : all_actions)
|
for (const auto& a : all_actions)
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ ExplosionAnimation *ExplosionAnimation::create(AbstractKart *kart)
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
||||||
const Vec3 &explosion_position,
|
const Vec3 &explosion_position,
|
||||||
bool direct_hit)
|
bool direct_hit, bool from_state)
|
||||||
: AbstractKartAnimation(kart, "ExplosionAnimation")
|
: AbstractKartAnimation(kart, "ExplosionAnimation")
|
||||||
{
|
{
|
||||||
m_direct_hit = direct_hit;
|
m_direct_hit = direct_hit;
|
||||||
@ -148,7 +148,8 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
|||||||
|
|
||||||
m_kart->getAttachment()->clear();
|
m_kart->getAttachment()->clear();
|
||||||
// Clear powerups when direct hit in CTF
|
// Clear powerups when direct hit in CTF
|
||||||
addNetworkAnimationChecker(m_reset_ticks != -1);
|
if (!from_state)
|
||||||
|
addNetworkAnimationChecker(m_reset_ticks != -1);
|
||||||
} // ExplosionAnimation
|
} // ExplosionAnimation
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -74,9 +74,9 @@ protected:
|
|||||||
Vec3 m_reset_xyz, m_reset_normal;
|
Vec3 m_reset_xyz, m_reset_normal;
|
||||||
|
|
||||||
ExplosionAnimation(AbstractKart *kart);
|
ExplosionAnimation(AbstractKart *kart);
|
||||||
ExplosionAnimation(AbstractKart *kart, const Vec3 &pos,
|
|
||||||
bool direct_hit);
|
|
||||||
public:
|
public:
|
||||||
|
ExplosionAnimation(AbstractKart *kart, const Vec3 &pos,
|
||||||
|
bool direct_hit, bool from_state = false);
|
||||||
static ExplosionAnimation *create(AbstractKart *kart, const Vec3 &pos,
|
static ExplosionAnimation *create(AbstractKart *kart, const Vec3 &pos,
|
||||||
bool direct_hit);
|
bool direct_hit);
|
||||||
static ExplosionAnimation *create(AbstractKart *kart);
|
static ExplosionAnimation *create(AbstractKart *kart);
|
||||||
@ -85,5 +85,8 @@ public:
|
|||||||
virtual void update(int ticks);
|
virtual void update(int ticks);
|
||||||
bool hasResetAlready() const
|
bool hasResetAlready() const
|
||||||
{ return m_reset_ticks != -1 && m_timer < m_reset_ticks; }
|
{ return m_reset_ticks != -1 && m_timer < m_reset_ticks; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual KartAnimationType getAnimationType() const
|
||||||
|
{ return m_direct_hit ? KAT_EXPLOSION_DIRECT_HIT : KAT_EXPLOSION; }
|
||||||
}; // ExplosionAnimation
|
}; // ExplosionAnimation
|
||||||
#endif
|
#endif
|
||||||
|
@ -185,7 +185,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
|||||||
m_terrain_sound = NULL;
|
m_terrain_sound = NULL;
|
||||||
m_last_sound_material = NULL;
|
m_last_sound_material = NULL;
|
||||||
m_previous_terrain_sound = NULL;
|
m_previous_terrain_sound = NULL;
|
||||||
|
m_graphical_view_blocked_by_plunger = 0.0f;
|
||||||
} // Kart
|
} // Kart
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -370,6 +370,7 @@ void Kart::reset()
|
|||||||
m_current_lean = 0.0f;
|
m_current_lean = 0.0f;
|
||||||
m_falling_time = 0.0f;
|
m_falling_time = 0.0f;
|
||||||
m_view_blocked_by_plunger = 0;
|
m_view_blocked_by_plunger = 0;
|
||||||
|
m_graphical_view_blocked_by_plunger = 0.0f;
|
||||||
m_has_caught_nolok_bubblegum = false;
|
m_has_caught_nolok_bubblegum = false;
|
||||||
m_is_jumping = false;
|
m_is_jumping = false;
|
||||||
m_flying = false;
|
m_flying = false;
|
||||||
@ -590,8 +591,15 @@ void Kart::blockViewWithPlunger()
|
|||||||
{
|
{
|
||||||
// Avoid that a plunger extends the plunger time
|
// Avoid that a plunger extends the plunger time
|
||||||
if(m_view_blocked_by_plunger<=0 && !isShielded())
|
if(m_view_blocked_by_plunger<=0 && !isShielded())
|
||||||
|
{
|
||||||
m_view_blocked_by_plunger =
|
m_view_blocked_by_plunger =
|
||||||
stk_config->time2Ticks(m_kart_properties->getPlungerInFaceTime());
|
stk_config->time2Ticks(m_kart_properties->getPlungerInFaceTime());
|
||||||
|
if (m_graphical_view_blocked_by_plunger == 0.0f)
|
||||||
|
{
|
||||||
|
m_graphical_view_blocked_by_plunger =
|
||||||
|
m_kart_properties->getPlungerInFaceTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
if(isShielded())
|
if(isShielded())
|
||||||
{
|
{
|
||||||
decreaseShieldTime();
|
decreaseShieldTime();
|
||||||
@ -875,22 +883,27 @@ float Kart::getSpeedForTurnRadius(float radius) const
|
|||||||
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
|
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
|
||||||
// Convert the turn radius into turn angle
|
// Convert the turn radius into turn angle
|
||||||
for(int i = 0; i < (int)turn_angle_at_speed.size(); i++)
|
for(int i = 0; i < (int)turn_angle_at_speed.size(); i++)
|
||||||
turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() /
|
turn_angle_at_speed.setY(i, sin( 1.0 / turn_angle_at_speed.getY(i)));
|
||||||
turn_angle_at_speed.getY(i)));
|
|
||||||
|
|
||||||
float angle = sin(m_kart_properties->getWheelBase() / radius);
|
float angle = sin(1.0 / radius);
|
||||||
return turn_angle_at_speed.getReverse(angle);
|
return turn_angle_at_speed.getReverse(angle);
|
||||||
} // getSpeedForTurnRadius
|
} // getSpeedForTurnRadius
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the maximum steering angle (depending on speed). */
|
/** Returns the maximum steering angle (depending on speed).
|
||||||
|
This is proportional to kart length because physics reverse this effect,
|
||||||
|
the results of this function should not be used to determine the
|
||||||
|
real raw steer angle. */
|
||||||
float Kart::getMaxSteerAngle(float speed) const
|
float Kart::getMaxSteerAngle(float speed) const
|
||||||
{
|
{
|
||||||
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
|
InterpolationArray turn_angle_at_speed = m_kart_properties->getTurnRadius();
|
||||||
// Convert the turn radius into turn angle
|
// Convert the turn radius into turn angle
|
||||||
|
// We multiply by wheel base to keep turn radius identical
|
||||||
|
// across karts of different lengths sharing the same
|
||||||
|
// turn radius properties
|
||||||
for(int i = 0; i < (int)turn_angle_at_speed.size(); i++)
|
for(int i = 0; i < (int)turn_angle_at_speed.size(); i++)
|
||||||
turn_angle_at_speed.setY(i, sin(m_kart_properties->getWheelBase() /
|
turn_angle_at_speed.setY(i, sin( 1.0 / turn_angle_at_speed.getY(i))
|
||||||
turn_angle_at_speed.getY(i)));
|
* m_kart_properties->getWheelBase());
|
||||||
|
|
||||||
return turn_angle_at_speed.get(speed);
|
return turn_angle_at_speed.get(speed);
|
||||||
} // getMaxSteerAngle
|
} // getMaxSteerAngle
|
||||||
@ -946,10 +959,16 @@ void Kart::finishedRace(float time, bool from_server)
|
|||||||
World::getWorld()->getTicksSinceStart(),
|
World::getWorld()->getTicksSinceStart(),
|
||||||
/*undo_function*/[old_controller, this]()
|
/*undo_function*/[old_controller, this]()
|
||||||
{
|
{
|
||||||
|
if (m_network_finish_check_ticks == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
m_controller = old_controller;
|
m_controller = old_controller;
|
||||||
},
|
},
|
||||||
/*replay_function*/[ec, old_controller, this]()
|
/*replay_function*/[ec, old_controller, this]()
|
||||||
{
|
{
|
||||||
|
if (m_network_finish_check_ticks == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
m_saved_controller = old_controller;
|
m_saved_controller = old_controller;
|
||||||
ec->reset();
|
ec->reset();
|
||||||
m_controller = ec;
|
m_controller = ec;
|
||||||
@ -1059,9 +1078,8 @@ void Kart::setRaceResult()
|
|||||||
}
|
}
|
||||||
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL)
|
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL)
|
||||||
{
|
{
|
||||||
// the top kart wins
|
|
||||||
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
|
||||||
m_race_result = ffa->getKartAtPosition(1) == this;
|
m_race_result = ffa->getKartFFAResult(getWorldKartId());
|
||||||
}
|
}
|
||||||
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
|
||||||
{
|
{
|
||||||
@ -1314,13 +1332,13 @@ void Kart::eliminate()
|
|||||||
*/
|
*/
|
||||||
void Kart::update(int ticks)
|
void Kart::update(int ticks)
|
||||||
{
|
{
|
||||||
if (m_network_finish_check_ticks != 0 &&
|
if (m_network_finish_check_ticks > 0 &&
|
||||||
World::getWorld()->getTicksSinceStart() >
|
World::getWorld()->getTicksSinceStart() >
|
||||||
m_network_finish_check_ticks &&
|
m_network_finish_check_ticks &&
|
||||||
!m_finished_race && m_saved_controller != NULL)
|
!m_finished_race && m_saved_controller != NULL)
|
||||||
{
|
{
|
||||||
Log::warn("Kart", "Missing finish race from server.");
|
Log::warn("Kart", "Missing finish race from server.");
|
||||||
m_network_finish_check_ticks = 0;
|
m_network_finish_check_ticks = -1;
|
||||||
delete m_controller;
|
delete m_controller;
|
||||||
m_controller = m_saved_controller;
|
m_controller = m_saved_controller;
|
||||||
m_saved_controller = NULL;
|
m_saved_controller = NULL;
|
||||||
@ -1423,7 +1441,10 @@ void Kart::update(int ticks)
|
|||||||
if(m_view_blocked_by_plunger > 0) m_view_blocked_by_plunger -= ticks;
|
if(m_view_blocked_by_plunger > 0) m_view_blocked_by_plunger -= ticks;
|
||||||
//unblock the view if kart just became shielded
|
//unblock the view if kart just became shielded
|
||||||
if(isShielded())
|
if(isShielded())
|
||||||
|
{
|
||||||
m_view_blocked_by_plunger = 0;
|
m_view_blocked_by_plunger = 0;
|
||||||
|
m_graphical_view_blocked_by_plunger = 0.0f;
|
||||||
|
}
|
||||||
// Decrease remaining invulnerability time
|
// Decrease remaining invulnerability time
|
||||||
if(m_invulnerable_ticks>0)
|
if(m_invulnerable_ticks>0)
|
||||||
{
|
{
|
||||||
@ -1532,7 +1553,7 @@ void Kart::update(int ticks)
|
|||||||
"v(16-18) %f %f %f steerf(20) %f maxangle(22) %f speed(24) %f "
|
"v(16-18) %f %f %f steerf(20) %f maxangle(22) %f speed(24) %f "
|
||||||
"steering(26-27) %f %f clock(29) %lf skidstate(31) %d factor(33) %f "
|
"steering(26-27) %f %f clock(29) %lf skidstate(31) %d factor(33) %f "
|
||||||
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
|
"maxspeed(35) %f engf(37) %f braketick(39) %d brakes(41) %d heading(43) %f "
|
||||||
"noderot(45) %f suslen %f",
|
"bubticks(45) %d bubtor(47) %f",
|
||||||
getIdent().c_str(),
|
getIdent().c_str(),
|
||||||
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
|
World::getWorld()->getTime(), World::getWorld()->getTicksSinceStart(),
|
||||||
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
|
getXYZ().getX(), getXYZ().getY(), getXYZ().getZ(),
|
||||||
@ -1553,8 +1574,8 @@ void Kart::update(int ticks)
|
|||||||
m_brake_ticks, //39
|
m_brake_ticks, //39
|
||||||
m_controls.getButtonsCompressed(), //41
|
m_controls.getButtonsCompressed(), //41
|
||||||
getHeading(), //43
|
getHeading(), //43
|
||||||
m_node->getAbsoluteTransformation().getRotationDegrees().Y, //45
|
m_bubblegum_ticks, // 45
|
||||||
m_vehicle->getWheelInfo(0).m_raycastInfo.m_suspensionLength
|
m_bubblegum_torque // 47
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
// After the physics step was done, the position of the wheels (as stored
|
// After the physics step was done, the position of the wheels (as stored
|
||||||
@ -1663,6 +1684,7 @@ void Kart::update(int ticks)
|
|||||||
if (emergency)
|
if (emergency)
|
||||||
{
|
{
|
||||||
m_view_blocked_by_plunger = 0;
|
m_view_blocked_by_plunger = 0;
|
||||||
|
m_graphical_view_blocked_by_plunger = 0.0f;
|
||||||
if (m_flying)
|
if (m_flying)
|
||||||
{
|
{
|
||||||
stopFlying();
|
stopFlying();
|
||||||
@ -3039,6 +3061,10 @@ void Kart::updateGraphics(float dt)
|
|||||||
unsetSquash();
|
unsetSquash();
|
||||||
}
|
}
|
||||||
} // if squashed
|
} // if squashed
|
||||||
|
if (m_graphical_view_blocked_by_plunger > 0.0f)
|
||||||
|
m_graphical_view_blocked_by_plunger -= dt;
|
||||||
|
if (m_graphical_view_blocked_by_plunger < 0.0f)
|
||||||
|
m_graphical_view_blocked_by_plunger = 0.0f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < EMITTER_COUNT; i++)
|
for (int i = 0; i < EMITTER_COUNT; i++)
|
||||||
|
@ -223,6 +223,9 @@ protected:
|
|||||||
/** When a kart has its view blocked by the plunger, this variable will be
|
/** When a kart has its view blocked by the plunger, this variable will be
|
||||||
* > 0 the number it contains is the time left before removing plunger. */
|
* > 0 the number it contains is the time left before removing plunger. */
|
||||||
int16_t m_view_blocked_by_plunger;
|
int16_t m_view_blocked_by_plunger;
|
||||||
|
|
||||||
|
float m_graphical_view_blocked_by_plunger;
|
||||||
|
|
||||||
/** The current speed (i.e. length of velocity vector) of this kart. */
|
/** The current speed (i.e. length of velocity vector) of this kart. */
|
||||||
float m_speed;
|
float m_speed;
|
||||||
|
|
||||||
@ -394,6 +397,9 @@ public:
|
|||||||
virtual int getBlockedByPlungerTicks() const OVERRIDE
|
virtual int getBlockedByPlungerTicks() const OVERRIDE
|
||||||
{ return m_view_blocked_by_plunger; }
|
{ return m_view_blocked_by_plunger; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
virtual float getGraphicalViewBlockedByPlunger() const OVERRIDE
|
||||||
|
{ return m_graphical_view_blocked_by_plunger; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Sets that the view is blocked by a plunger. The duration depends on
|
/** Sets that the view is blocked by a plunger. The duration depends on
|
||||||
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
* the difficulty, see KartPorperties getPlungerInFaceTime. */
|
||||||
virtual void blockViewWithPlunger() OVERRIDE;
|
virtual void blockViewWithPlunger() OVERRIDE;
|
||||||
|
@ -303,17 +303,12 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
|||||||
m_gravity_center_shift.setZ(0);
|
m_gravity_center_shift.setZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In older STK versions the physical wheels where moved 'wheel_radius'
|
// The longer the kart,the bigger its turn radius if using an identical
|
||||||
// into the physical body (i.e. 'hypothetical' wheel shape would not
|
// wheel base, exactly proportionally to its length.
|
||||||
// poke out of the physical shape). In order to make the karts a bit more
|
// The wheel base is used to compensate this
|
||||||
// stable, the physical wheel position (i.e. location of raycast) were
|
// We divide by 1.425 to have a default turn radius which conforms
|
||||||
// moved to be on the corner of the shape. In order to retain the same
|
// closely (+-0,1%) with the specifications in kart_characteristics.xml
|
||||||
// steering behaviour, the wheel base (which in turn determines the
|
m_wheel_base = fabsf(m_kart_model->getLength()/1.425f);
|
||||||
// turn angle at certain speeds) is shortened by 2*wheel_radius
|
|
||||||
// Wheel radius was always 0.25, and is now not used anymore, but in order
|
|
||||||
// to keep existing steering behaviour, the same formula is still
|
|
||||||
// used.
|
|
||||||
m_wheel_base = fabsf(m_kart_model->getLength() - 2*0.25f);
|
|
||||||
|
|
||||||
m_shadow_material = material_manager->getMaterialSPM(m_shadow_file, "",
|
m_shadow_material = material_manager->getMaterialSPM(m_shadow_file, "",
|
||||||
"alphablend");
|
"alphablend");
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#include "items/attachment.hpp"
|
#include "items/attachment.hpp"
|
||||||
#include "items/powerup.hpp"
|
#include "items/powerup.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
#include "karts/abstract_kart_animation.hpp"
|
#include "karts/explosion_animation.hpp"
|
||||||
|
#include "karts/rescue_animation.hpp"
|
||||||
#include "karts/controller/player_controller.hpp"
|
#include "karts/controller/player_controller.hpp"
|
||||||
#include "karts/kart_properties.hpp"
|
#include "karts/kart_properties.hpp"
|
||||||
#include "karts/max_speed.hpp"
|
#include "karts/max_speed.hpp"
|
||||||
@ -52,6 +53,7 @@ KartRewinder::KartRewinder(const std::string& ident,
|
|||||||
*/
|
*/
|
||||||
void KartRewinder::reset()
|
void KartRewinder::reset()
|
||||||
{
|
{
|
||||||
|
m_last_animation_end_ticks = -1;
|
||||||
m_transfrom_from_network =
|
m_transfrom_from_network =
|
||||||
btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f));
|
btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
Kart::reset();
|
Kart::reset();
|
||||||
@ -138,7 +140,9 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
|
|||||||
buffer->add(trans.getOrigin());
|
buffer->add(trans.getOrigin());
|
||||||
btQuaternion quat = trans.getRotation();
|
btQuaternion quat = trans.getRotation();
|
||||||
buffer->add(quat);
|
buffer->add(quat);
|
||||||
buffer->addUInt32(ka->getEndTicks());
|
unsigned et = ka->getEndTicks() & 134217727;
|
||||||
|
et |= ka->getAnimationType() << 27;
|
||||||
|
buffer->addUInt32(et);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -207,10 +211,38 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
|
|||||||
|
|
||||||
if (has_animation)
|
if (has_animation)
|
||||||
{
|
{
|
||||||
int end_ticks = buffer->getUInt32();
|
unsigned et = buffer->getUInt32();
|
||||||
AbstractKartAnimation* ka = getKartAnimation();
|
int end_ticks = et & 134217727;
|
||||||
if (ka)
|
KartAnimationType kat = (KartAnimationType)(et >> 27);
|
||||||
ka->setEndTransformTicks(m_transfrom_from_network, end_ticks);
|
if (!getKartAnimation() && end_ticks != m_last_animation_end_ticks)
|
||||||
|
{
|
||||||
|
Log::info("KartRewinder", "Creating animation %d from state", kat);
|
||||||
|
switch (kat)
|
||||||
|
{
|
||||||
|
case KAT_RESCUE:
|
||||||
|
new RescueAnimation(this, false/*is_auto_rescue*/,
|
||||||
|
true/*from_state*/);
|
||||||
|
break;
|
||||||
|
case KAT_EXPLOSION_DIRECT_HIT:
|
||||||
|
new ExplosionAnimation(this, getSmoothedXYZ(),
|
||||||
|
true/*direct_hit*/, true/*from_state*/);
|
||||||
|
break;
|
||||||
|
case KAT_EXPLOSION:
|
||||||
|
new ExplosionAnimation(this, getSmoothedXYZ(),
|
||||||
|
false/*direct_hit*/, true/*from_state*/);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log::warn("KartRewinder", "Unknown animation %d from state",
|
||||||
|
kat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getKartAnimation())
|
||||||
|
{
|
||||||
|
getKartAnimation()->setEndTransformTicks(m_transfrom_from_network,
|
||||||
|
end_ticks);
|
||||||
|
}
|
||||||
|
m_last_animation_end_ticks = end_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 lv = buffer->getVec3();
|
Vec3 lv = buffer->getVec3();
|
||||||
|
@ -33,6 +33,7 @@ private:
|
|||||||
btTransform m_transfrom_from_network;
|
btTransform m_transfrom_from_network;
|
||||||
float m_prev_steering, m_steering_smoothing_dt, m_steering_smoothing_time;
|
float m_prev_steering, m_steering_smoothing_dt, m_steering_smoothing_time;
|
||||||
|
|
||||||
|
int m_last_animation_end_ticks;
|
||||||
public:
|
public:
|
||||||
KartRewinder(const std::string& ident, unsigned int world_kart_id,
|
KartRewinder(const std::string& ident, unsigned int world_kart_id,
|
||||||
int position, const btTransform& init_transform,
|
int position, const btTransform& init_transform,
|
||||||
|
@ -40,7 +40,8 @@
|
|||||||
* and initialised the timer.
|
* and initialised the timer.
|
||||||
* \param kart Pointer to the kart which is animated.
|
* \param kart Pointer to the kart which is animated.
|
||||||
*/
|
*/
|
||||||
RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
|
RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue,
|
||||||
|
bool from_state)
|
||||||
: AbstractKartAnimation(kart, "RescueAnimation")
|
: AbstractKartAnimation(kart, "RescueAnimation")
|
||||||
{
|
{
|
||||||
btTransform prev_trans = kart->getTrans();
|
btTransform prev_trans = kart->getTrans();
|
||||||
@ -89,8 +90,11 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear powerups when rescue in CTF
|
// Clear powerups when rescue in CTF
|
||||||
addNetworkAnimationChecker(race_manager->getMajorMode() ==
|
if (!from_state)
|
||||||
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG);
|
{
|
||||||
|
addNetworkAnimationChecker(race_manager->getMajorMode() ==
|
||||||
|
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG);
|
||||||
|
}
|
||||||
} // RescueAnimation
|
} // RescueAnimation
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -49,9 +49,13 @@ protected:
|
|||||||
Referee *m_referee;
|
Referee *m_referee;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RescueAnimation(AbstractKart *kart, bool is_auto_rescue=false);
|
RescueAnimation(AbstractKart *kart,
|
||||||
|
bool is_auto_rescue = false,
|
||||||
|
bool from_state = false);
|
||||||
float maximumHeight();
|
float maximumHeight();
|
||||||
virtual ~RescueAnimation();
|
virtual ~RescueAnimation();
|
||||||
virtual void update(int ticks);
|
virtual void update(int ticks);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual KartAnimationType getAnimationType() const { return KAT_RESCUE; }
|
||||||
}; // RescueAnimation
|
}; // RescueAnimation
|
||||||
#endif
|
#endif
|
||||||
|
@ -421,6 +421,7 @@ void Skidding::update(int ticks, bool is_on_ground,
|
|||||||
m_predicted_curve->setHeading(m_kart->getHeading());
|
m_predicted_curve->setHeading(m_kart->getHeading());
|
||||||
float angle = m_kart->getMaxSteerAngle(SPEED)
|
float angle = m_kart->getMaxSteerAngle(SPEED)
|
||||||
* fabsf(getSteeringFraction());
|
* fabsf(getSteeringFraction());
|
||||||
|
//FIXME : what is this for ?
|
||||||
float r = kp->getWheelBase()
|
float r = kp->getWheelBase()
|
||||||
/ asin(angle)*1.0f;
|
/ asin(angle)*1.0f;
|
||||||
|
|
||||||
|
10
src/main.cpp
10
src/main.cpp
@ -1936,8 +1936,11 @@ int main(int argc, char *argv[] )
|
|||||||
}
|
}
|
||||||
else if (CommandLine::has("--lan-server", &s))
|
else if (CommandLine::has("--lan-server", &s))
|
||||||
{
|
{
|
||||||
ProfileWorld::disableGraphics();
|
if (no_graphics)
|
||||||
UserConfigParams::m_enable_sound = false;
|
{
|
||||||
|
ProfileWorld::disableGraphics();
|
||||||
|
UserConfigParams::m_enable_sound = false;
|
||||||
|
}
|
||||||
NetworkConfig::get()->setIsServer(true);
|
NetworkConfig::get()->setIsServer(true);
|
||||||
ServerConfig::m_server_name = s;
|
ServerConfig::m_server_name = s;
|
||||||
ServerConfig::m_wan_server = false;
|
ServerConfig::m_wan_server = false;
|
||||||
@ -2354,7 +2357,8 @@ static void cleanSuperTuxKart()
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (!ProfileWorld::isNoGraphics())
|
if (!ProfileWorld::isNoGraphics())
|
||||||
{
|
{
|
||||||
if(!NewsManager::get()->waitForReadyToDeleted(2.0f))
|
if (UserConfigParams::m_internet_status == Online::RequestManager::
|
||||||
|
IPERM_ALLOWED && !NewsManager::get()->waitForReadyToDeleted(2.0f))
|
||||||
{
|
{
|
||||||
Log::info("Thread", "News manager not stopping, exiting anyway.");
|
Log::info("Thread", "News manager not stopping, exiting anyway.");
|
||||||
}
|
}
|
||||||
|
@ -55,10 +55,10 @@ void override_default_params()
|
|||||||
{
|
{
|
||||||
case ACONFIGURATION_SCREENSIZE_SMALL:
|
case ACONFIGURATION_SCREENSIZE_SMALL:
|
||||||
case ACONFIGURATION_SCREENSIZE_NORMAL:
|
case ACONFIGURATION_SCREENSIZE_NORMAL:
|
||||||
UserConfigParams::m_multitouch_scale = 1.3f;
|
UserConfigParams::m_multitouch_scale = 1.4f;
|
||||||
break;
|
break;
|
||||||
case ACONFIGURATION_SCREENSIZE_LARGE:
|
case ACONFIGURATION_SCREENSIZE_LARGE:
|
||||||
UserConfigParams::m_multitouch_scale = 1.2f;
|
UserConfigParams::m_multitouch_scale = 1.3f;
|
||||||
break;
|
break;
|
||||||
case ACONFIGURATION_SCREENSIZE_XLARGE:
|
case ACONFIGURATION_SCREENSIZE_XLARGE:
|
||||||
UserConfigParams::m_multitouch_scale = 1.1f;
|
UserConfigParams::m_multitouch_scale = 1.1f;
|
||||||
|
@ -308,16 +308,22 @@ void MainLoop::run()
|
|||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
if (msg.message == WM_QUIT)
|
if (msg.message == WM_QUIT)
|
||||||
m_abort = true;
|
{
|
||||||
|
m_request_abort = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If parent is killed, abort the child main loop too
|
// If parent is killed, abort the child main loop too
|
||||||
if (WaitForSingleObject(parent, 0) != WAIT_TIMEOUT)
|
if (WaitForSingleObject(parent, 0) != WAIT_TIMEOUT)
|
||||||
m_abort = true;
|
{
|
||||||
|
m_request_abort = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// POSIX equivalent
|
// POSIX equivalent
|
||||||
if (m_parent_pid != 0 && getppid() != (int)m_parent_pid)
|
if (m_parent_pid != 0 && getppid() != (int)m_parent_pid)
|
||||||
m_abort = true;
|
{
|
||||||
|
m_request_abort = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
PROFILER_PUSH_CPU_MARKER("Main loop", 0xFF, 0x00, 0xF7);
|
PROFILER_PUSH_CPU_MARKER("Main loop", 0xFF, 0x00, 0xF7);
|
||||||
|
|
||||||
@ -328,23 +334,28 @@ void MainLoop::run()
|
|||||||
|
|
||||||
// Shutdown next frame if shutdown request is sent while loading the
|
// Shutdown next frame if shutdown request is sent while loading the
|
||||||
// world
|
// world
|
||||||
if (STKHost::existHost() &&
|
if ((STKHost::existHost() && STKHost::get()->requestedShutdown()) ||
|
||||||
(STKHost::get()->requestedShutdown() || m_request_abort))
|
m_request_abort)
|
||||||
{
|
{
|
||||||
|
bool exist_host = STKHost::existHost();
|
||||||
core::stringw msg = _("Server connection timed out.");
|
core::stringw msg = _("Server connection timed out.");
|
||||||
|
|
||||||
if (!ProfileWorld::isNoGraphics())
|
if (!m_request_abort)
|
||||||
{
|
{
|
||||||
SFXManager::get()->quickSound("anvil");
|
if (!ProfileWorld::isNoGraphics())
|
||||||
if (!STKHost::get()->getErrorMessage().empty())
|
|
||||||
{
|
{
|
||||||
msg = STKHost::get()->getErrorMessage();
|
SFXManager::get()->quickSound("anvil");
|
||||||
|
if (!STKHost::get()->getErrorMessage().empty())
|
||||||
|
{
|
||||||
|
msg = STKHost::get()->getErrorMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STKHost::get()->shutdown();
|
if (exist_host == true)
|
||||||
// In case the user opened a race pause dialog
|
{
|
||||||
GUIEngine::ModalDialog::dismiss();
|
STKHost::get()->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (CVS->isGLSL())
|
if (CVS->isGLSL())
|
||||||
@ -357,24 +368,32 @@ void MainLoop::run()
|
|||||||
irr_driver->getActualScreenSize().Height);
|
irr_driver->getActualScreenSize().Height);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// In case the user opened a race pause dialog
|
||||||
|
GUIEngine::ModalDialog::dismiss();
|
||||||
|
|
||||||
if (World::getWorld())
|
if (World::getWorld())
|
||||||
{
|
{
|
||||||
race_manager->clearNetworkGrandPrixResult();
|
race_manager->clearNetworkGrandPrixResult();
|
||||||
race_manager->exitRace();
|
race_manager->exitRace();
|
||||||
}
|
}
|
||||||
if (!ProfileWorld::isNoGraphics())
|
|
||||||
|
if (exist_host == true)
|
||||||
{
|
{
|
||||||
StateManager::get()->resetAndSetStack(
|
if (!ProfileWorld::isNoGraphics())
|
||||||
NetworkConfig::get()->getResetScreens().data());
|
{
|
||||||
MessageQueue::add(MessageQueue::MT_ERROR, msg);
|
StateManager::get()->resetAndSetStack(
|
||||||
|
NetworkConfig::get()->getResetScreens().data());
|
||||||
|
MessageQueue::add(MessageQueue::MT_ERROR, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConfig::get()->unsetNetworking();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_request_abort)
|
||||||
|
{
|
||||||
|
m_abort = true;
|
||||||
}
|
}
|
||||||
NetworkConfig::get()->unsetNetworking();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_request_abort)
|
|
||||||
{
|
|
||||||
m_abort = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_abort)
|
if (!m_abort)
|
||||||
@ -404,84 +423,96 @@ void MainLoop::run()
|
|||||||
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
|
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
|
||||||
Online::RequestManager::get()->update(frame_duration);
|
Online::RequestManager::get()->update(frame_duration);
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
}
|
|
||||||
|
|
||||||
m_ticks_adjustment.lock();
|
m_ticks_adjustment.lock();
|
||||||
if (m_ticks_adjustment.getData() != 0)
|
if (m_ticks_adjustment.getData() != 0)
|
||||||
{
|
|
||||||
if (m_ticks_adjustment.getData() > 0)
|
|
||||||
{
|
{
|
||||||
num_steps += m_ticks_adjustment.getData();
|
if (m_ticks_adjustment.getData() > 0)
|
||||||
m_ticks_adjustment.getData() = 0;
|
|
||||||
}
|
|
||||||
else if (m_ticks_adjustment.getData() < 0)
|
|
||||||
{
|
|
||||||
int new_steps = num_steps + m_ticks_adjustment.getData();
|
|
||||||
if (new_steps < 0)
|
|
||||||
{
|
{
|
||||||
num_steps = 0;
|
num_steps += m_ticks_adjustment.getData();
|
||||||
m_ticks_adjustment.getData() = new_steps;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
num_steps = new_steps;
|
|
||||||
m_ticks_adjustment.getData() = 0;
|
m_ticks_adjustment.getData() = 0;
|
||||||
}
|
}
|
||||||
}
|
else if (m_ticks_adjustment.getData() < 0)
|
||||||
}
|
|
||||||
m_ticks_adjustment.unlock();
|
|
||||||
|
|
||||||
for(int i=0; i<num_steps; i++)
|
|
||||||
{
|
|
||||||
if (World::getWorld() && history->replayHistory())
|
|
||||||
history->updateReplay(World::getWorld()->getTicksSinceStart());
|
|
||||||
|
|
||||||
PROFILER_PUSH_CPU_MARKER("Protocol manager update",
|
|
||||||
0x7F, 0x00, 0x7F);
|
|
||||||
if (auto pm = ProtocolManager::lock())
|
|
||||||
{
|
|
||||||
pm->update(1);
|
|
||||||
}
|
|
||||||
PROFILER_POP_CPU_MARKER();
|
|
||||||
|
|
||||||
PROFILER_PUSH_CPU_MARKER("Update race", 0, 255, 255);
|
|
||||||
if (World::getWorld()) updateRace(1);
|
|
||||||
PROFILER_POP_CPU_MARKER();
|
|
||||||
|
|
||||||
// We need to check again because update_race may have requested
|
|
||||||
// the main loop to abort; and it's not a good idea to continue
|
|
||||||
// since the GUI engine is no more to be called then.
|
|
||||||
if (m_abort) break;
|
|
||||||
|
|
||||||
if (m_frame_before_loading_world)
|
|
||||||
{
|
|
||||||
m_frame_before_loading_world = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (World::getWorld())
|
|
||||||
{
|
|
||||||
if (World::getWorld()->getPhase() == WorldStatus::SETUP_PHASE)
|
|
||||||
{
|
{
|
||||||
// Skip the large num steps contributed by loading time
|
int new_steps = num_steps + m_ticks_adjustment.getData();
|
||||||
World::getWorld()->updateTime(1);
|
if (new_steps < 0)
|
||||||
|
{
|
||||||
|
num_steps = 0;
|
||||||
|
m_ticks_adjustment.getData() = new_steps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num_steps = new_steps;
|
||||||
|
m_ticks_adjustment.getData() = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_ticks_adjustment.unlock();
|
||||||
|
|
||||||
|
for (int i = 0; i < num_steps; i++)
|
||||||
|
{
|
||||||
|
if (World::getWorld() && history->replayHistory())
|
||||||
|
{
|
||||||
|
history->updateReplay(
|
||||||
|
World::getWorld()->getTicksSinceStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
PROFILER_PUSH_CPU_MARKER("Protocol manager update",
|
||||||
|
0x7F, 0x00, 0x7F);
|
||||||
|
if (auto pm = ProtocolManager::lock())
|
||||||
|
{
|
||||||
|
pm->update(1);
|
||||||
|
}
|
||||||
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
|
PROFILER_PUSH_CPU_MARKER("Update race", 0, 255, 255);
|
||||||
|
if (World::getWorld())
|
||||||
|
{
|
||||||
|
updateRace(1);
|
||||||
|
}
|
||||||
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
|
||||||
|
// We need to check again because update_race may have requested
|
||||||
|
// the main loop to abort; and it's not a good idea to continue
|
||||||
|
// since the GUI engine is no more to be called then.
|
||||||
|
if (m_abort || m_request_abort)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (m_frame_before_loading_world)
|
||||||
|
{
|
||||||
|
m_frame_before_loading_world = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
World::getWorld()->updateTime(1);
|
|
||||||
}
|
if (World::getWorld())
|
||||||
} // for i < num_steps
|
{
|
||||||
|
if (World::getWorld()->getPhase()==WorldStatus::SETUP_PHASE)
|
||||||
|
{
|
||||||
|
// Skip the large num steps contributed by loading time
|
||||||
|
World::getWorld()->updateTime(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
World::getWorld()->updateTime(1);
|
||||||
|
}
|
||||||
|
} // for i < num_steps
|
||||||
|
|
||||||
// Handle controller the last to avoid slow PC sending actions too late
|
// Handle controller the last to avoid slow PC sending actions too
|
||||||
if (!m_abort)
|
// late
|
||||||
{
|
|
||||||
if (!ProfileWorld::isNoGraphics())
|
if (!ProfileWorld::isNoGraphics())
|
||||||
{
|
{
|
||||||
// User aborted (e.g. closed window)
|
// User aborted (e.g. closed window)
|
||||||
bool abort = !irr_driver->getDevice()->run();
|
bool abort = !irr_driver->getDevice()->run();
|
||||||
|
|
||||||
if (abort)
|
if (abort)
|
||||||
m_abort = true;
|
{
|
||||||
|
m_request_abort = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto gp = GameProtocol::lock())
|
if (auto gp = GameProtocol::lock())
|
||||||
|
{
|
||||||
gp->sendActions();
|
gp->sendActions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PROFILER_POP_CPU_MARKER(); // MainLoop pop
|
PROFILER_POP_CPU_MARKER(); // MainLoop pop
|
||||||
PROFILER_SYNC_FRAME();
|
PROFILER_SYNC_FRAME();
|
||||||
|
@ -159,7 +159,8 @@ const std::string& EasterEggHunt::getIdent() const
|
|||||||
/** Called when a kart has collected an egg.
|
/** Called when a kart has collected an egg.
|
||||||
* \param kart The kart that collected an egg.
|
* \param kart The kart that collected an egg.
|
||||||
*/
|
*/
|
||||||
void EasterEggHunt::collectedItem(const AbstractKart *kart, const Item *item)
|
void EasterEggHunt::collectedItem(const AbstractKart *kart,
|
||||||
|
const ItemState *item )
|
||||||
{
|
{
|
||||||
if(item->getType() != ItemState::ITEM_EASTER_EGG) return;
|
if(item->getType() != ItemState::ITEM_EASTER_EGG) return;
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||||
virtual void collectedItem(const AbstractKart *kart,
|
virtual void collectedItem(const AbstractKart *kart,
|
||||||
const Item *item ) OVERRIDE;
|
const ItemState *item ) OVERRIDE;
|
||||||
void collectedEasterEggGhost(int world_id);
|
void collectedEasterEggGhost(int world_id);
|
||||||
|
|
||||||
const int numberOfEggsFound() { return m_eggs_found; }
|
const int numberOfEggsFound() { return m_eggs_found; }
|
||||||
|
@ -196,3 +196,14 @@ video::SColor FreeForAll::getColor(unsigned int kart_id) const
|
|||||||
{
|
{
|
||||||
return GUIEngine::getSkin()->getColor("font::normal");
|
return GUIEngine::getSkin()->getColor("font::normal");
|
||||||
} // getColor
|
} // getColor
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
bool FreeForAll::getKartFFAResult(int kart_id) const
|
||||||
|
{
|
||||||
|
// the kart(s) which has the top score wins
|
||||||
|
AbstractKart* k = getKartAtPosition(1);
|
||||||
|
if (!k)
|
||||||
|
return false;
|
||||||
|
int top_score = getKartScore(k->getWorldKartId());
|
||||||
|
return getKartScore(kart_id) == top_score;
|
||||||
|
} // getKartFFAResult
|
||||||
|
@ -66,6 +66,8 @@ public:
|
|||||||
void setKartScoreFromServer(NetworkString& ns);
|
void setKartScoreFromServer(NetworkString& ns);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
int getKartScore(int kart_id) const { return m_scores.at(kart_id); }
|
int getKartScore(int kart_id) const { return m_scores.at(kart_id); }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool getKartFFAResult(int kart_id) const;
|
||||||
}; // FreeForAll
|
}; // FreeForAll
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,11 +213,11 @@ const std::string& SoccerWorld::getIdent() const
|
|||||||
void SoccerWorld::update(int ticks)
|
void SoccerWorld::update(int ticks)
|
||||||
{
|
{
|
||||||
updateBallPosition(ticks);
|
updateBallPosition(ticks);
|
||||||
updateSectorForKarts();
|
if (Track::getCurrentTrack()->hasNavMesh())
|
||||||
if (Track::getCurrentTrack()->hasNavMesh() &&
|
|
||||||
!NetworkConfig::get()->isNetworking())
|
|
||||||
{
|
{
|
||||||
updateAIData();
|
updateSectorForKarts();
|
||||||
|
if (!NetworkConfig::get()->isNetworking())
|
||||||
|
updateAIData();
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldWithRank::update(ticks);
|
WorldWithRank::update(ticks);
|
||||||
@ -652,6 +652,9 @@ int SoccerWorld::getAttacker(KartTeam team) const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
unsigned int SoccerWorld::getRescuePositionIndex(AbstractKart *kart)
|
unsigned int SoccerWorld::getRescuePositionIndex(AbstractKart *kart)
|
||||||
{
|
{
|
||||||
|
if (!Track::getCurrentTrack()->hasNavMesh())
|
||||||
|
return m_kart_position_map.at(kart->getWorldKartId());
|
||||||
|
|
||||||
int last_valid_node =
|
int last_valid_node =
|
||||||
getTrackSector(kart->getWorldKartId())->getLastValidGraphNode();
|
getTrackSector(kart->getWorldKartId())->getLastValidGraphNode();
|
||||||
if (last_valid_node >= 0)
|
if (last_valid_node >= 0)
|
||||||
@ -663,6 +666,9 @@ unsigned int SoccerWorld::getRescuePositionIndex(AbstractKart *kart)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
btTransform SoccerWorld::getRescueTransform(unsigned int rescue_pos) const
|
btTransform SoccerWorld::getRescueTransform(unsigned int rescue_pos) const
|
||||||
{
|
{
|
||||||
|
if (!Track::getCurrentTrack()->hasNavMesh())
|
||||||
|
return WorldWithRank::getRescueTransform(rescue_pos);
|
||||||
|
|
||||||
const Vec3 &xyz = Graph::get()->getQuad(rescue_pos)->getCenter();
|
const Vec3 &xyz = Graph::get()->getQuad(rescue_pos)->getCenter();
|
||||||
const Vec3 &normal = Graph::get()->getQuad(rescue_pos)->getNormal();
|
const Vec3 &normal = Graph::get()->getQuad(rescue_pos)->getNormal();
|
||||||
btTransform pos;
|
btTransform pos;
|
||||||
|
@ -587,6 +587,9 @@ void World::onGo()
|
|||||||
*/
|
*/
|
||||||
void World::terminateRace()
|
void World::terminateRace()
|
||||||
{
|
{
|
||||||
|
// In case the user opened paused dialog in network
|
||||||
|
GUIEngine::ModalDialog::dismiss();
|
||||||
|
|
||||||
m_schedule_pause = false;
|
m_schedule_pause = false;
|
||||||
m_schedule_unpause = false;
|
m_schedule_unpause = false;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
class AbstractKart;
|
class AbstractKart;
|
||||||
class btRigidBody;
|
class btRigidBody;
|
||||||
class Controller;
|
class Controller;
|
||||||
class Item;
|
class ItemState;
|
||||||
class PhysicalObject;
|
class PhysicalObject;
|
||||||
|
|
||||||
namespace Scripting
|
namespace Scripting
|
||||||
@ -263,7 +263,8 @@ public:
|
|||||||
int *amount );
|
int *amount );
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Receives notification if an item is collected. Used for easter eggs. */
|
/** Receives notification if an item is collected. Used for easter eggs. */
|
||||||
virtual void collectedItem(const AbstractKart *kart, const Item *item) {}
|
virtual void collectedItem(const AbstractKart *kart,
|
||||||
|
const ItemState *item ) {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void endRaceEarly() { return; }
|
virtual void endRaceEarly() { return; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -154,8 +154,27 @@ void RewindManager::saveState()
|
|||||||
|
|
||||||
m_overall_state_size = 0;
|
m_overall_state_size = 0;
|
||||||
std::vector<std::string> rewinder_using;
|
std::vector<std::string> rewinder_using;
|
||||||
|
|
||||||
|
// We must save the item state first (so that it is restored first),
|
||||||
|
// otherwise state updates for a kart could be overwritten by
|
||||||
|
// e.g. simulating the item collection later (which resets bubblegum
|
||||||
|
// counter).
|
||||||
|
BareNetworkString* buffer = NULL;
|
||||||
|
if(auto r = m_all_rewinder["N"].lock())
|
||||||
|
buffer = r->saveState(&rewinder_using);
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
m_overall_state_size += buffer->size();
|
||||||
|
gp->addState(buffer);
|
||||||
|
}
|
||||||
|
delete buffer; // buffer can be freed
|
||||||
|
|
||||||
for (auto& p : m_all_rewinder)
|
for (auto& p : m_all_rewinder)
|
||||||
{
|
{
|
||||||
|
// The Network ItemManager was saved first before this loop,
|
||||||
|
// so skip it here.
|
||||||
|
if(p.first=="N") continue;
|
||||||
|
|
||||||
// TODO: check if it's worth passing in a sufficiently large buffer from
|
// TODO: check if it's worth passing in a sufficiently large buffer from
|
||||||
// GameProtocol - this would save the copy operation.
|
// GameProtocol - this would save the copy operation.
|
||||||
BareNetworkString* buffer = NULL;
|
BareNetworkString* buffer = NULL;
|
||||||
|
@ -136,7 +136,7 @@ void loadServerConfigXML(const XMLNode* root)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_file_version = -1;
|
/*int config_file_version = -1;
|
||||||
if (root->get("version", &config_file_version) < 1 ||
|
if (root->get("version", &config_file_version) < 1 ||
|
||||||
config_file_version < stk_config->m_min_server_version ||
|
config_file_version < stk_config->m_min_server_version ||
|
||||||
config_file_version > stk_config->m_max_server_version)
|
config_file_version > stk_config->m_max_server_version)
|
||||||
@ -146,7 +146,7 @@ void loadServerConfigXML(const XMLNode* root)
|
|||||||
delete root;
|
delete root;
|
||||||
writeServerConfigToDisk();
|
writeServerConfigToDisk();
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
for (unsigned i = 0; i < g_server_params.size(); i++)
|
for (unsigned i = 0; i < g_server_params.size(); i++)
|
||||||
g_server_params[i]->findYourDataInAChildOf(root);
|
g_server_params[i]->findYourDataInAChildOf(root);
|
||||||
|
@ -269,7 +269,7 @@ namespace ServerConfig
|
|||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
/** Server version, will be advanced if there are protocol changes. */
|
/** Server version, will be advanced if there are protocol changes. */
|
||||||
static const uint32_t m_server_version = 1;
|
static const uint32_t m_server_version = 2;
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
void loadServerConfig(const std::string& path = "");
|
void loadServerConfig(const std::string& path = "");
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -634,8 +634,7 @@ void STKHost::setErrorMessage(const irr::core::stringw &message)
|
|||||||
{
|
{
|
||||||
if (!message.empty())
|
if (!message.empty())
|
||||||
{
|
{
|
||||||
irr::core::stringc s(message.c_str());
|
Log::error("STKHost", "%s", StringUtils::wideToUtf8(message).c_str());
|
||||||
Log::error("STKHost", "%s", s.c_str());
|
|
||||||
}
|
}
|
||||||
m_error_message = message;
|
m_error_message = message;
|
||||||
} // setErrorMessage
|
} // setErrorMessage
|
||||||
|
@ -326,7 +326,11 @@ namespace Online
|
|||||||
setProgress(-1.0f);
|
setProgress(-1.0f);
|
||||||
|
|
||||||
Request::afterOperation();
|
Request::afterOperation();
|
||||||
curl_easy_cleanup(m_curl_session);
|
if (m_curl_session)
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(m_curl_session);
|
||||||
|
m_curl_session = NULL;
|
||||||
|
}
|
||||||
} // afterOperation
|
} // afterOperation
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -63,7 +63,7 @@ namespace Online
|
|||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
|
||||||
/** Pointer to the curl data structure for this request. */
|
/** Pointer to the curl data structure for this request. */
|
||||||
CURL *m_curl_session;
|
CURL *m_curl_session = NULL;
|
||||||
|
|
||||||
/** curl return code. */
|
/** curl return code. */
|
||||||
CURLcode m_curl_code;
|
CURLcode m_curl_code;
|
||||||
@ -93,7 +93,14 @@ namespace Online
|
|||||||
int priority = 1);
|
int priority = 1);
|
||||||
HTTPRequest(const char * const filename, bool manage_memory = false,
|
HTTPRequest(const char * const filename, bool manage_memory = false,
|
||||||
int priority = 1);
|
int priority = 1);
|
||||||
virtual ~HTTPRequest() {}
|
virtual ~HTTPRequest()
|
||||||
|
{
|
||||||
|
if (m_curl_session)
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(m_curl_session);
|
||||||
|
m_curl_session = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual bool isAllowedToAdd() const OVERRIDE;
|
virtual bool isAllowedToAdd() const OVERRIDE;
|
||||||
void setApiURL(const std::string& url, const std::string &action);
|
void setApiURL(const std::string& url, const std::string &action);
|
||||||
void setAddonsURL(const std::string& path);
|
void setAddonsURL(const std::string& path);
|
||||||
|
@ -213,7 +213,13 @@ namespace Online
|
|||||||
me->m_current_request->execute();
|
me->m_current_request->execute();
|
||||||
// This test is necessary in case that execute() was aborted
|
// This test is necessary in case that execute() was aborted
|
||||||
// (otherwise the assert in addResult will be triggered).
|
// (otherwise the assert in addResult will be triggered).
|
||||||
if (!me->getAbort()) me->addResult(me->m_current_request);
|
if (!me->getAbort())
|
||||||
|
me->addResult(me->m_current_request);
|
||||||
|
else if (me->m_current_request->manageMemory())
|
||||||
|
{
|
||||||
|
delete me->m_current_request;
|
||||||
|
me->m_current_request = NULL;
|
||||||
|
}
|
||||||
me->m_request_queue.lock();
|
me->m_request_queue.lock();
|
||||||
} // while handle all requests
|
} // while handle all requests
|
||||||
|
|
||||||
|
@ -139,10 +139,10 @@ GUIEngine::EventPropagation MultitouchSettingsDialog::processEvent(
|
|||||||
{
|
{
|
||||||
case ACONFIGURATION_SCREENSIZE_SMALL:
|
case ACONFIGURATION_SCREENSIZE_SMALL:
|
||||||
case ACONFIGURATION_SCREENSIZE_NORMAL:
|
case ACONFIGURATION_SCREENSIZE_NORMAL:
|
||||||
UserConfigParams::m_multitouch_scale = 1.3f;
|
UserConfigParams::m_multitouch_scale = 1.4f;
|
||||||
break;
|
break;
|
||||||
case ACONFIGURATION_SCREENSIZE_LARGE:
|
case ACONFIGURATION_SCREENSIZE_LARGE:
|
||||||
UserConfigParams::m_multitouch_scale = 1.2f;
|
UserConfigParams::m_multitouch_scale = 1.3f;
|
||||||
break;
|
break;
|
||||||
case ACONFIGURATION_SCREENSIZE_XLARGE:
|
case ACONFIGURATION_SCREENSIZE_XLARGE:
|
||||||
UserConfigParams::m_multitouch_scale = 1.1f;
|
UserConfigParams::m_multitouch_scale = 1.1f;
|
||||||
|
@ -52,9 +52,15 @@ GhostReplaySelection::~GhostReplaySelection()
|
|||||||
void GhostReplaySelection::tearDown()
|
void GhostReplaySelection::tearDown()
|
||||||
{
|
{
|
||||||
m_replay_list_widget->setIcons(NULL);
|
m_replay_list_widget->setIcons(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GhostReplaySelection::unloaded()
|
||||||
|
{
|
||||||
delete m_icon_bank;
|
delete m_icon_bank;
|
||||||
m_icon_bank = NULL;
|
m_icon_bank = NULL;
|
||||||
}
|
} // unloaded
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Triggers a refresh of the replay file list.
|
/** Triggers a refresh of the replay file list.
|
||||||
@ -117,6 +123,24 @@ void GhostReplaySelection::loadedFromFile()
|
|||||||
m_mode_tabs = getWidget<GUIEngine::RibbonWidget>("race_mode");
|
m_mode_tabs = getWidget<GUIEngine::RibbonWidget>("race_mode");
|
||||||
m_active_mode = RaceManager::MINOR_MODE_TIME_TRIAL;
|
m_active_mode = RaceManager::MINOR_MODE_TIME_TRIAL;
|
||||||
m_active_mode_is_linear = true;
|
m_active_mode_is_linear = true;
|
||||||
|
|
||||||
|
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv());
|
||||||
|
|
||||||
|
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++)
|
||||||
|
{
|
||||||
|
const KartProperties* prop = kart_properties_manager->getKartById(i);
|
||||||
|
m_icon_bank->addTextureAsSprite(prop->getIconMaterial()->getTexture());
|
||||||
|
}
|
||||||
|
|
||||||
|
video::ITexture* kart_not_found = irr_driver->getTexture(
|
||||||
|
file_manager->getAsset(FileManager::GUI_ICON, "main_help.png"));
|
||||||
|
|
||||||
|
m_icon_unknown_kart = m_icon_bank->addTextureAsSprite(kart_not_found);
|
||||||
|
|
||||||
|
video::ITexture* lock = irr_driver->getTexture( file_manager->getAsset(
|
||||||
|
FileManager::GUI_ICON, "gui_lock.png"));
|
||||||
|
|
||||||
|
m_icon_lock = m_icon_bank->addTextureAsSprite(lock);
|
||||||
} // loadedFromFile
|
} // loadedFromFile
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -148,24 +172,6 @@ void GhostReplaySelection::init()
|
|||||||
Screen::init();
|
Screen::init();
|
||||||
m_cur_difficulty = race_manager->getDifficulty();
|
m_cur_difficulty = race_manager->getDifficulty();
|
||||||
|
|
||||||
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv());
|
|
||||||
|
|
||||||
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++)
|
|
||||||
{
|
|
||||||
const KartProperties* prop = kart_properties_manager->getKartById(i);
|
|
||||||
m_icon_bank->addTextureAsSprite(prop->getIconMaterial()->getTexture());
|
|
||||||
}
|
|
||||||
|
|
||||||
video::ITexture* kart_not_found = irr_driver->getTexture( file_manager->getAsset(FileManager::GUI_ICON,
|
|
||||||
"main_help.png" ));
|
|
||||||
|
|
||||||
m_icon_unknown_kart = m_icon_bank->addTextureAsSprite(kart_not_found);
|
|
||||||
|
|
||||||
video::ITexture* lock = irr_driver->getTexture( file_manager->getAsset(FileManager::GUI_ICON,
|
|
||||||
"gui_lock.png" ));
|
|
||||||
|
|
||||||
m_icon_lock = m_icon_bank->addTextureAsSprite(lock);
|
|
||||||
|
|
||||||
int icon_height = getHeight()/24;
|
int icon_height = getHeight()/24;
|
||||||
// 128 is the height of the image file
|
// 128 is the height of the image file
|
||||||
//FIXME : this isn't guaranteed
|
//FIXME : this isn't guaranteed
|
||||||
|
@ -106,6 +106,8 @@ public:
|
|||||||
virtual void init() OVERRIDE;
|
virtual void init() OVERRIDE;
|
||||||
|
|
||||||
virtual void tearDown() OVERRIDE;
|
virtual void tearDown() OVERRIDE;
|
||||||
|
|
||||||
|
virtual void unloaded() OVERRIDE;
|
||||||
|
|
||||||
virtual bool onEscapePressed() OVERRIDE;
|
virtual bool onEscapePressed() OVERRIDE;
|
||||||
|
|
||||||
|
@ -258,9 +258,9 @@ void CreateServerScreen::createServer()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool private_server = !password.empty();
|
||||||
ServerConfig::m_private_server_password = password;
|
ServerConfig::m_private_server_password = password;
|
||||||
if (!password.empty())
|
password = std::string(" --server-password=") + password;
|
||||||
password = std::string(" --server-password=") + password;
|
|
||||||
|
|
||||||
TransportAddress server_address(0x7f000001,
|
TransportAddress server_address(0x7f000001,
|
||||||
stk_config->m_server_discovery_port);
|
stk_config->m_server_discovery_port);
|
||||||
@ -268,7 +268,7 @@ void CreateServerScreen::createServer()
|
|||||||
auto server = std::make_shared<Server>(0/*server_id*/, name,
|
auto server = std::make_shared<Server>(0/*server_id*/, name,
|
||||||
max_players, /*current_player*/0, (RaceManager::Difficulty)
|
max_players, /*current_player*/0, (RaceManager::Difficulty)
|
||||||
difficulty_widget->getSelection(PLAYER_ID_GAME_MASTER),
|
difficulty_widget->getSelection(PLAYER_ID_GAME_MASTER),
|
||||||
0, server_address, !password.empty(), false);
|
0, server_address, private_server, false);
|
||||||
|
|
||||||
#undef USE_GRAPHICS_SERVER
|
#undef USE_GRAPHICS_SERVER
|
||||||
#ifdef USE_GRAPHICS_SERVER
|
#ifdef USE_GRAPHICS_SERVER
|
||||||
|
@ -274,7 +274,6 @@ void OptionsScreenVideo::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ANDROID
|
|
||||||
if (!found_config_res)
|
if (!found_config_res)
|
||||||
{
|
{
|
||||||
r.width = UserConfigParams::m_width;
|
r.width = UserConfigParams::m_width;
|
||||||
@ -291,6 +290,7 @@ void OptionsScreenVideo::init()
|
|||||||
}
|
}
|
||||||
} // next found resolution
|
} // next found resolution
|
||||||
|
|
||||||
|
#ifndef ANDROID
|
||||||
// Add default resolutions that were not found by irrlicht
|
// Add default resolutions that were not found by irrlicht
|
||||||
if (!found_1024_768)
|
if (!found_1024_768)
|
||||||
{
|
{
|
||||||
|
@ -270,12 +270,13 @@ void RaceGUI::renderGlobal(float dt)
|
|||||||
if(world->getPhase() == World::GOAL_PHASE)
|
if(world->getPhase() == World::GOAL_PHASE)
|
||||||
drawGlobalGoal();
|
drawGlobalGoal();
|
||||||
|
|
||||||
|
if (!m_enabled) return;
|
||||||
|
|
||||||
// MiniMap is drawn when the players wait for the start countdown to end
|
// MiniMap is drawn when the players wait for the start countdown to end
|
||||||
drawGlobalMiniMap();
|
drawGlobalMiniMap();
|
||||||
|
|
||||||
// Timer etc. are not displayed unless the game is actually started.
|
// Timer etc. are not displayed unless the game is actually started.
|
||||||
if(!world->isRacePhase()) return;
|
if(!world->isRacePhase()) return;
|
||||||
if (!m_enabled) return;
|
|
||||||
|
|
||||||
//drawGlobalTimer checks if it should display in the current phase/mode
|
//drawGlobalTimer checks if it should display in the current phase/mode
|
||||||
drawGlobalTimer();
|
drawGlobalTimer();
|
||||||
@ -539,7 +540,8 @@ void RaceGUI::drawGlobalMiniMap()
|
|||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
//TODO : exception for some game modes ? Another option "Hidden in race, shown in battle ?"
|
//TODO : exception for some game modes ? Another option "Hidden in race, shown in battle ?"
|
||||||
if(UserConfigParams::m_minimap_display == 2 /*map hidden*/)
|
if (UserConfigParams::m_minimap_display == 2 /*map hidden*/ ||
|
||||||
|
UserConfigParams::m_multitouch_scale > 1.3f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// draw a map when arena has a navigation mesh.
|
// draw a map when arena has a navigation mesh.
|
||||||
|
@ -670,8 +670,8 @@ void RaceGUIBase::drawGlobalReadySetGo()
|
|||||||
} // drawGlobalReadySetGo
|
} // drawGlobalReadySetGo
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Draw players icons and their times (if defined in the current mode).
|
/** Draw players icons and, depending on the current mode, their time
|
||||||
* Also takes care of icon looking different due to plumber, squashing, ...
|
* or their score (battle lives, egg collected, etc.).
|
||||||
*/
|
*/
|
||||||
void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
||||||
{
|
{
|
||||||
@ -1138,3 +1138,5 @@ void RaceGUIBase::removeReferee()
|
|||||||
m_referee->removeFromSceneGraph();
|
m_referee->removeFromSceneGraph();
|
||||||
}
|
}
|
||||||
} // removeReferee
|
} // removeReferee
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
|
|||||||
|
|
||||||
m_device = input_manager->getDeviceManager()->getMultitouchDevice();
|
m_device = input_manager->getDeviceManager()->getMultitouchDevice();
|
||||||
|
|
||||||
if (UserConfigParams::m_multitouch_scale > 1.5f)
|
if (UserConfigParams::m_multitouch_scale > 1.6f)
|
||||||
{
|
{
|
||||||
UserConfigParams::m_multitouch_scale = 1.5f;
|
UserConfigParams::m_multitouch_scale = 1.6f;
|
||||||
}
|
}
|
||||||
else if (UserConfigParams::m_multitouch_scale < 0.5f)
|
else if (UserConfigParams::m_multitouch_scale < 0.8f)
|
||||||
{
|
{
|
||||||
UserConfigParams::m_multitouch_scale = 0.5f;
|
UserConfigParams::m_multitouch_scale = 0.8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@ -340,6 +340,7 @@ void RaceGUIMultitouch::draw(const AbstractKart* kart,
|
|||||||
}
|
}
|
||||||
else if (button->type == MultitouchButtonType::BUTTON_FIRE &&
|
else if (button->type == MultitouchButtonType::BUTTON_FIRE &&
|
||||||
kart->getPowerup()->getNum() > 1 &&
|
kart->getPowerup()->getNum() > 1 &&
|
||||||
|
!kart->hasFinishedRace() &&
|
||||||
m_gui_action == false)
|
m_gui_action == false)
|
||||||
{
|
{
|
||||||
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
|
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
|
||||||
|
@ -2492,6 +2492,10 @@ Vec3 Track::flagCommand(const XMLNode *node)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_track_object_manager->castRay
|
||||||
|
(loc, loc + (-10000 * quad_normal), &hit_point, &m, &normal,
|
||||||
|
/*interpolate*/false);
|
||||||
|
|
||||||
const std::string &name = node->getName();
|
const std::string &name = node->getName();
|
||||||
if (name == "red-flag")
|
if (name == "red-flag")
|
||||||
{
|
{
|
||||||
|
@ -167,9 +167,11 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
|
|||||||
else if (type == "sfx-emitter")
|
else if (type == "sfx-emitter")
|
||||||
{
|
{
|
||||||
// FIXME: at this time sound emitters are just disabled in multiplayer
|
// FIXME: at this time sound emitters are just disabled in multiplayer
|
||||||
// otherwise the sounds would be constantly heard
|
// otherwise the sounds would be constantly heard, for networking
|
||||||
if (race_manager->getNumLocalPlayers() < 2)
|
// the index of item needs to be same so we create and disable it
|
||||||
m_presentation = new TrackObjectPresentationSound(xml_node, parent);
|
// in TrackObjectPresentationSound constructor
|
||||||
|
m_presentation = new TrackObjectPresentationSound(xml_node, parent,
|
||||||
|
race_manager->getNumLocalPlayers() > 1);
|
||||||
}
|
}
|
||||||
else if (type == "action-trigger")
|
else if (type == "action-trigger")
|
||||||
{
|
{
|
||||||
|
@ -652,7 +652,8 @@ void TrackObjectPresentationMesh::reset()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
TrackObjectPresentationSound::TrackObjectPresentationSound(
|
TrackObjectPresentationSound::TrackObjectPresentationSound(
|
||||||
const XMLNode& xml_node,
|
const XMLNode& xml_node,
|
||||||
scene::ISceneNode* parent)
|
scene::ISceneNode* parent,
|
||||||
|
bool disable_for_multiplayer)
|
||||||
: TrackObjectPresentation(xml_node)
|
: TrackObjectPresentation(xml_node)
|
||||||
{
|
{
|
||||||
// TODO: respect 'parent' if any
|
// TODO: respect 'parent' if any
|
||||||
@ -680,6 +681,13 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(
|
|||||||
float max_dist = 390.0f;
|
float max_dist = 390.0f;
|
||||||
xml_node.get("max_dist", &max_dist );
|
xml_node.get("max_dist", &max_dist );
|
||||||
|
|
||||||
|
if (trigger_when_near)
|
||||||
|
{
|
||||||
|
ItemManager::get()->placeTrigger(m_init_xyz, trigger_distance, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disable_for_multiplayer)
|
||||||
|
return;
|
||||||
// first try track dir, then global dir
|
// first try track dir, then global dir
|
||||||
std::string soundfile = Track::getCurrentTrack()->getTrackFile(sound);
|
std::string soundfile = Track::getCurrentTrack()->getTrackFile(sound);
|
||||||
//std::string soundfile = file_manager->getAsset(FileManager::MODEL,sound);
|
//std::string soundfile = file_manager->getAsset(FileManager::MODEL,sound);
|
||||||
@ -708,10 +716,6 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(
|
|||||||
else
|
else
|
||||||
Log::error("TrackObject", "Sound emitter object could not be created.");
|
Log::error("TrackObject", "Sound emitter object could not be created.");
|
||||||
|
|
||||||
if (trigger_when_near)
|
|
||||||
{
|
|
||||||
ItemManager::get()->placeTrigger(m_init_xyz, trigger_distance, this);
|
|
||||||
}
|
|
||||||
} // TrackObjectPresentationSound
|
} // TrackObjectPresentationSound
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -286,7 +286,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
TrackObjectPresentationSound(const XMLNode& xml_node,
|
TrackObjectPresentationSound(const XMLNode& xml_node,
|
||||||
scene::ISceneNode* parent);
|
scene::ISceneNode* parent,
|
||||||
|
bool disable_for_multiplayer);
|
||||||
virtual ~TrackObjectPresentationSound();
|
virtual ~TrackObjectPresentationSound();
|
||||||
virtual void onTriggerItemApproached() OVERRIDE;
|
virtual void onTriggerItemApproached() OVERRIDE;
|
||||||
virtual void update(float dt) OVERRIDE;
|
virtual void update(float dt) OVERRIDE;
|
||||||
|
@ -283,9 +283,27 @@ bool SeparateProcess::createChildProcess(const std::string& exe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string data_path = AssetsAndroid::getDataPath();
|
std::string data_path = AssetsAndroid::getDataPath();
|
||||||
std::string main_path = data_path + "/lib/libmain.so";
|
std::string main_path;
|
||||||
|
|
||||||
if (data_path.empty() || access(main_path.c_str(), R_OK) != 0)
|
if (!data_path.empty())
|
||||||
|
{
|
||||||
|
main_path = data_path + "/lib/libmain.so";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (main_path.empty() || access(main_path.c_str(), R_OK) != 0)
|
||||||
|
{
|
||||||
|
std::string lib_path = AssetsAndroid::getLibPath();
|
||||||
|
|
||||||
|
if (!lib_path.empty())
|
||||||
|
{
|
||||||
|
main_path = lib_path + "/libmain.so";
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("SeparateProcess", "Trying to use fallback lib path: %s",
|
||||||
|
main_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (main_path.empty() || access(main_path.c_str(), R_OK) != 0)
|
||||||
{
|
{
|
||||||
Log::error("SeparateProcess", "Error: Cannot read libmain.so");
|
Log::error("SeparateProcess", "Error: Cannot read libmain.so");
|
||||||
return false;
|
return false;
|
||||||
|
194
tools/android_builder.sh
Executable file
194
tools/android_builder.sh
Executable file
@ -0,0 +1,194 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# (C) 2018 Dawid Gan, under the GPLv3
|
||||||
|
#
|
||||||
|
# A script that builds Android APKs for all architectures
|
||||||
|
#
|
||||||
|
# The script assumes that you know what you are doing. It allows to generate all
|
||||||
|
# packages for Google Play Store with single command. If you just want to build
|
||||||
|
# STK for your own use, then use android/make.sh script instead.
|
||||||
|
|
||||||
|
export BUILD_TYPE=Beta
|
||||||
|
export PROJECT_VERSION=git20181001
|
||||||
|
export PROJECT_CODE=48
|
||||||
|
export STOREPASS="xxx"
|
||||||
|
export KEYSTORE="/path/to/stk.keystore"
|
||||||
|
export ALIAS="alias"
|
||||||
|
|
||||||
|
|
||||||
|
check_error()
|
||||||
|
{
|
||||||
|
if [ $? -gt 0 ]; then
|
||||||
|
echo "Error ocurred."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
clean()
|
||||||
|
{
|
||||||
|
echo "Clean everything"
|
||||||
|
|
||||||
|
rm -rf ./android-armv7
|
||||||
|
rm -rf ./android-aarch64
|
||||||
|
rm -rf ./android-x86
|
||||||
|
rm -rf ./android-x86_64
|
||||||
|
rm -rf ./android/assets
|
||||||
|
rm -rf ./android-output
|
||||||
|
|
||||||
|
cd android
|
||||||
|
./make.sh clean
|
||||||
|
cd -
|
||||||
|
}
|
||||||
|
|
||||||
|
init_directories()
|
||||||
|
{
|
||||||
|
echo "Init directories"
|
||||||
|
|
||||||
|
if [ ! -d "./android-armv7" ]; then
|
||||||
|
echo "Creating android-armv7 directory"
|
||||||
|
|
||||||
|
mkdir android-armv7
|
||||||
|
cd android-armv7
|
||||||
|
|
||||||
|
ln -s ../android/Android.mk
|
||||||
|
ln -s ../android/AndroidManifest.xml
|
||||||
|
ln -s ../android/banner.png
|
||||||
|
ln -s ../android/build.gradle
|
||||||
|
ln -s ../android/icon.png
|
||||||
|
ln -s ../android/icon-dbg.png
|
||||||
|
ln -s ../android/make.sh
|
||||||
|
ln -s ../android/android-ndk
|
||||||
|
ln -s ../android/android-sdk
|
||||||
|
ln -s ../android/assets
|
||||||
|
|
||||||
|
cd -
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "./android-aarch64" ]; then
|
||||||
|
echo "Creating android-aarch64 directory"
|
||||||
|
cp -a ./android-armv7 ./android-aarch64
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "./android-x86" ]; then
|
||||||
|
echo "Creating android-x86 directory"
|
||||||
|
cp -a ./android-armv7 ./android-x86
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "./android-x86_64" ]; then
|
||||||
|
echo "Creating android-x86_64 directory"
|
||||||
|
cp -a ./android-armv7 ./android-x86_64
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "./android-output" ]; then
|
||||||
|
echo "Creating android-output directory"
|
||||||
|
mkdir ./android-output
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_assets()
|
||||||
|
{
|
||||||
|
echo "Generate assets"
|
||||||
|
|
||||||
|
if [ -d "./android/assets" ]; then
|
||||||
|
echo "Assets already found in ./android/assets"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ./android
|
||||||
|
./generate_assets.sh
|
||||||
|
|
||||||
|
if [ ! -f "./assets/directories.txt" ]; then
|
||||||
|
echo "Error: Couldn't generate assets"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "./assets/data/supertuxkart.git" ]; then
|
||||||
|
mv "./assets/data/supertuxkart.git" \
|
||||||
|
"./assets/data/supertuxkart.$PROJECT_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd -
|
||||||
|
}
|
||||||
|
|
||||||
|
build_package()
|
||||||
|
{
|
||||||
|
export ARCH1=$1
|
||||||
|
export ARCH2=$2
|
||||||
|
|
||||||
|
echo "Build package for $ARCH1"
|
||||||
|
|
||||||
|
if [ -f "./android-output/SuperTuxKart-$PROJECT_VERSION-$ARCH1.apk" ]; then
|
||||||
|
echo "Package for architecture $ARCH1 is already built"
|
||||||
|
#return
|
||||||
|
fi
|
||||||
|
|
||||||
|
export COMPILE_ARCH=$ARCH1
|
||||||
|
|
||||||
|
cd ./android-$ARCH1
|
||||||
|
./make.sh -j5
|
||||||
|
cd -
|
||||||
|
|
||||||
|
if [ ! -f ./android-$ARCH1/build/outputs/apk/android-$ARCH1-release-unsigned.apk ]; then
|
||||||
|
echo "Error: Couldn't build apk for architecture $ARCH1"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp ./android-$ARCH1/build/outputs/apk/android-$ARCH1-release-unsigned.apk \
|
||||||
|
./android-output/SuperTuxKart-$PROJECT_VERSION-$ARCH1-unaligned.apk
|
||||||
|
|
||||||
|
cp ./android-$ARCH1/obj/local/$ARCH2/libmain.so \
|
||||||
|
./android-output/SuperTuxKart-$PROJECT_VERSION-$ARCH1-libmain.so
|
||||||
|
|
||||||
|
cd ./android-output
|
||||||
|
|
||||||
|
jarsigner -sigalg SHA1withRSA -digestalg SHA1 \
|
||||||
|
-keystore "$KEYSTORE" \
|
||||||
|
-storepass "$STOREPASS" \
|
||||||
|
SuperTuxKart-$PROJECT_VERSION-$ARCH1-unaligned.apk \
|
||||||
|
"$ALIAS"
|
||||||
|
|
||||||
|
check_error
|
||||||
|
|
||||||
|
zipalign -f 4 SuperTuxKart-$PROJECT_VERSION-$ARCH1-unaligned.apk \
|
||||||
|
SuperTuxKart-$PROJECT_VERSION-$ARCH1.apk
|
||||||
|
|
||||||
|
check_error
|
||||||
|
|
||||||
|
rm SuperTuxKart-$PROJECT_VERSION-$ARCH1-unaligned.apk
|
||||||
|
|
||||||
|
cd -
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Handle clean command
|
||||||
|
if [ ! -z "$1" ] && [ "$1" = "clean" ]; then
|
||||||
|
clean
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Build packages
|
||||||
|
init_directories
|
||||||
|
|
||||||
|
generate_assets
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ "$1" = "armv7" ]; then
|
||||||
|
build_package armv7 armeabi-v7a
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_CODE=$(($PROJECT_CODE + 1))
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ "$1" = "aarch64" ]; then
|
||||||
|
build_package aarch64 arm64-v8a
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_CODE=$(($PROJECT_CODE + 1))
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ "$1" = "x86" ]; then
|
||||||
|
build_package x86 x86
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_CODE=$(($PROJECT_CODE + 1))
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ "$1" = "x86_64" ]; then
|
||||||
|
build_package x86_64 x86_64
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user