Merge remote-tracking branch 'origin/master' into lensdust
This commit is contained in:
commit
a19119a2f2
Binary file not shown.
@ -426,7 +426,7 @@
|
|||||||
chassis-angular-damping="0"
|
chassis-angular-damping="0"
|
||||||
downward-impulse-factor="5"
|
downward-impulse-factor="5"
|
||||||
track-connection-accel="2"
|
track-connection-accel="2"
|
||||||
smooth-flying-impulse="25"/>
|
smooth-flying-impulse="250"/>
|
||||||
|
|
||||||
<!-- collision
|
<!-- collision
|
||||||
impulse-type: STK can apply an additional impulse in case of
|
impulse-type: STK can apply an additional impulse in case of
|
||||||
@ -623,7 +623,7 @@
|
|||||||
time-reset-steer="0.1" />
|
time-reset-steer="0.1" />
|
||||||
|
|
||||||
<!-- Speed and acceleration related values: power and max-speed (in m/s)
|
<!-- Speed and acceleration related values: power and max-speed (in m/s)
|
||||||
have 3 values, one for low, medium, and hard.
|
have 4 values, one for low, medium, hard, and supertux.
|
||||||
brake-factor: Value used when braking.
|
brake-factor: Value used when braking.
|
||||||
brake-time-increase: The brake force is multiplied by
|
brake-time-increase: The brake force is multiplied by
|
||||||
(1+brake_time*brake_time_increase - i.e. the longer the brake was
|
(1+brake_time*brake_time_increase - i.e. the longer the brake was
|
||||||
|
2
data/supertuxkart.git
Normal file
2
data/supertuxkart.git
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
This file is only here to help STK finding the right directory,
|
||||||
|
and to avoid problems with other directories called 'data'.
|
@ -11,6 +11,9 @@
|
|||||||
#include "IVideoDriver.h"
|
#include "IVideoDriver.h"
|
||||||
#include "rect.h"
|
#include "rect.h"
|
||||||
|
|
||||||
|
#define CJK_START 12287
|
||||||
|
#define CJK_END 40960
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
@ -360,6 +363,20 @@ void CGUIStaticText::breakText()
|
|||||||
{
|
{
|
||||||
// part of a word
|
// part of a word
|
||||||
word += c;
|
word += c;
|
||||||
|
|
||||||
|
//Check for CJK, show them first if out of range of displaying area
|
||||||
|
if (Text[i] > CJK_START && Text[i] < CJK_END)
|
||||||
|
{
|
||||||
|
const s32 cjklgth = font->getDimension(word.c_str()).Width;
|
||||||
|
if (cjklgth > (elWidth - 23))
|
||||||
|
{
|
||||||
|
BrokenText.push_back(line);
|
||||||
|
length = cjklgth;
|
||||||
|
line = word;
|
||||||
|
word = L"";
|
||||||
|
whitespace = L"";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isWhitespace || i == (size-1))
|
if ( isWhitespace || i == (size-1))
|
||||||
|
@ -173,9 +173,10 @@ void SavedGrandPrix::loadKarts(std::vector<RaceManager::KartStatus> & kart_list)
|
|||||||
{
|
{
|
||||||
if(kart_list[x].m_local_player_id == m_karts[i].m_local_player_id)
|
if(kart_list[x].m_local_player_id == m_karts[i].m_local_player_id)
|
||||||
{
|
{
|
||||||
|
if(kp) kart_list[x].m_ident = m_karts[i].m_ident;
|
||||||
kart_list[x].m_score = m_karts[i].m_score;
|
kart_list[x].m_score = m_karts[i].m_score;
|
||||||
kart_list[x].m_overall_time = m_karts[i].m_overall_time;
|
kart_list[x].m_overall_time = m_karts[i].m_overall_time;
|
||||||
} // if kart_list[x].m_local_player_id == m_karts[i].,_local
|
} // if kart_list[x].m_local_player_id == m_karts[i].local
|
||||||
} // for x
|
} // for x
|
||||||
} // if m_local_player_id == -1
|
} // if m_local_player_id == -1
|
||||||
} // for i
|
} // for i
|
||||||
|
@ -77,12 +77,7 @@ int LODNode::getLevel()
|
|||||||
Camera* camera = Camera::getActiveCamera();
|
Camera* camera = Camera::getActiveCamera();
|
||||||
if (camera == NULL)
|
if (camera == NULL)
|
||||||
return (int)m_detail.size() - 1;
|
return (int)m_detail.size() - 1;
|
||||||
AbstractKart* kart = camera->getKart();
|
const Vec3 &pos = camera->getCameraSceneNode()->getAbsolutePosition();
|
||||||
// use kart position and not camera position when a kart is available,
|
|
||||||
// because for some effects the camera will be moved to various locations
|
|
||||||
// (for instance shadows), so using camera position for LOD may result
|
|
||||||
// in objects being culled when they shouldn't
|
|
||||||
const Vec3 &pos = (kart != NULL ? kart->getFrontXYZ() : camera->getCameraSceneNode()->getAbsolutePosition());
|
|
||||||
|
|
||||||
const int dist =
|
const int dist =
|
||||||
(int)((m_nodes[0]->getAbsolutePosition()).getDistanceFromSQ(pos.toIrrVector() ));
|
(int)((m_nodes[0]->getAbsolutePosition()).getDistanceFromSQ(pos.toIrrVector() ));
|
||||||
|
@ -84,21 +84,19 @@ Material::Material(const XMLNode *node, bool deprecated)
|
|||||||
|
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
//node->get("adjust-image", &s );
|
|
||||||
//if(s=="premultiply")
|
|
||||||
// m_adjust_image = ADJ_PREMUL;
|
|
||||||
//else if (s=="divide")
|
|
||||||
// m_adjust_image = ADJ_DIV;
|
|
||||||
//else if (s=="" || s=="none")
|
|
||||||
// m_adjust_image = ADJ_NONE;
|
|
||||||
//else
|
|
||||||
// Log::warn("material",
|
|
||||||
// "Incorrect adjust-image specification: '%s' - ignored.",
|
|
||||||
// s.c_str());
|
|
||||||
|
|
||||||
node->get("high-adhesion", &m_high_tire_adhesion);
|
|
||||||
node->get("reset", &m_drive_reset );
|
|
||||||
|
|
||||||
|
node->get("high-adhesion", &m_high_tire_adhesion );
|
||||||
|
node->get("reset", &m_drive_reset );
|
||||||
|
s = "";
|
||||||
|
node->get("mirror-axis", &s);
|
||||||
|
if (s == "u")
|
||||||
|
s = "U";
|
||||||
|
else if (s == "v")
|
||||||
|
s = "V";
|
||||||
|
if (s != "U" && s != "V")
|
||||||
|
m_mirror_axis_when_reverse = ' ';
|
||||||
|
else
|
||||||
|
m_mirror_axis_when_reverse = s[0];
|
||||||
// backwards compatibility
|
// backwards compatibility
|
||||||
bool crash_reset = false;
|
bool crash_reset = false;
|
||||||
node->get("crash-reset", &crash_reset );
|
node->get("crash-reset", &crash_reset );
|
||||||
@ -433,6 +431,7 @@ void Material::init()
|
|||||||
m_surface = false;
|
m_surface = false;
|
||||||
m_ignore = false;
|
m_ignore = false;
|
||||||
m_drive_reset = false;
|
m_drive_reset = false;
|
||||||
|
m_mirror_axis_when_reverse = ' ';
|
||||||
m_collision_reaction = NORMAL;
|
m_collision_reaction = NORMAL;
|
||||||
m_disable_z_write = false;
|
m_disable_z_write = false;
|
||||||
m_water_shader_speed_1 = 6.6667f;
|
m_water_shader_speed_1 = 6.6667f;
|
||||||
|
@ -156,6 +156,11 @@ private:
|
|||||||
|
|
||||||
bool m_fog;
|
bool m_fog;
|
||||||
|
|
||||||
|
/** Either ' ' (no mirroring), 'U' or 'V' if a texture needs to be
|
||||||
|
* mirrored when driving in reverse. Typically used for arrows indicating
|
||||||
|
* the direction. */
|
||||||
|
char m_mirror_axis_when_reverse;
|
||||||
|
|
||||||
ParticleKind* m_particles_effects[EMIT_KINDS_COUNT];
|
ParticleKind* m_particles_effects[EMIT_KINDS_COUNT];
|
||||||
|
|
||||||
/** For normal maps */
|
/** For normal maps */
|
||||||
@ -373,6 +378,9 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
ShaderType getShaderType() const { return m_shader_type; }
|
ShaderType getShaderType() const { return m_shader_type; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** True if this texture should have the U coordinates mirrored. */
|
||||||
|
char getMirrorAxisInReverse() const { return m_mirror_axis_when_reverse; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ void IconButtonWidget::add()
|
|||||||
x1 += diff;
|
x1 += diff;
|
||||||
x2 += diff;
|
x2 += diff;
|
||||||
}
|
}
|
||||||
else if (x2 > irr_driver->getActualScreenSize().Width)
|
else if (x2 > (int)irr_driver->getActualScreenSize().Width)
|
||||||
{
|
{
|
||||||
int diff = x2 - irr_driver->getActualScreenSize().Width;
|
int diff = x2 - irr_driver->getActualScreenSize().Width;
|
||||||
x2 -= diff;
|
x2 -= diff;
|
||||||
|
@ -560,7 +560,9 @@ EventPropagation RibbonWidget::focused(const int playerID)
|
|||||||
{
|
{
|
||||||
if (m_selection[playerID] != -1)
|
if (m_selection[playerID] != -1)
|
||||||
{
|
{
|
||||||
m_active_children.get(m_selection[playerID])->focused(playerID);
|
int selection = m_selection[playerID];
|
||||||
|
if (selection < m_active_children.size())
|
||||||
|
m_active_children.get(selection)->focused(playerID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,45 +110,85 @@ irr::core::stringw Binding::getAsString() const
|
|||||||
case 221: s="]"; break;
|
case 221: s="]"; break;
|
||||||
case 222: s="'"; break;
|
case 222: s="'"; break;
|
||||||
#endif
|
#endif
|
||||||
case irr::KEY_LBUTTON : s = "left mouse button"; break;
|
//I18N: input configuration screen: mouse button
|
||||||
case irr::KEY_RBUTTON : s = "right mouse button"; break;
|
case irr::KEY_LBUTTON : s = _("Left Mouse Button"); break;
|
||||||
case irr::KEY_CANCEL : s = "cancel"; break;
|
//I18N: input configuration screen: mouse button
|
||||||
case irr::KEY_MBUTTON : s = "middle mouse button"; break;
|
case irr::KEY_RBUTTON : s = _("Right Mouse Button"); break;
|
||||||
case irr::KEY_XBUTTON1 : s = "X1 mouse button"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_XBUTTON2 : s = "X2 mouse button"; break;
|
case irr::KEY_CANCEL : s = _("Cancel"); break;
|
||||||
case irr::KEY_BACK : s = "backspace"; break;
|
//I18N: input configuration screen: mouse button
|
||||||
case irr::KEY_TAB : s = "tab"; break;
|
case irr::KEY_MBUTTON : s = _("Middle Mouse Button"); break;
|
||||||
case irr::KEY_CLEAR : s = "clear"; break;
|
//I18N: input configuration screen: mouse button
|
||||||
case irr::KEY_RETURN : s = "return"; break;
|
case irr::KEY_XBUTTON1 : s = _("X1 Mouse Button"); break;
|
||||||
case irr::KEY_SHIFT : s = "shift"; break;
|
//I18N: input configuration screen: mouse button
|
||||||
case irr::KEY_CONTROL : s = "control"; break;
|
case irr::KEY_XBUTTON2 : s = _("X2 Mouse Button"); break;
|
||||||
case irr::KEY_MENU : s = "alt/menu"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_PAUSE : s = "pause"; break;
|
case irr::KEY_BACK : s = _("Backspace"); break;
|
||||||
case irr::KEY_CAPITAL : s = "caps lock"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_KANA : s = "kana"; break;
|
case irr::KEY_TAB : s = _("Tab"); break;
|
||||||
case irr::KEY_JUNJA : s = "junja"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_FINAL : s = "final"; break;
|
case irr::KEY_CLEAR : s = _("Clear"); break;
|
||||||
case irr::KEY_ESCAPE : s = "escape"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_CONVERT : s = "convert"; break;
|
case irr::KEY_RETURN : s = _("Return"); break;
|
||||||
case irr::KEY_NONCONVERT : s = "nonconvert"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_ACCEPT : s = "accept"; break;
|
case irr::KEY_SHIFT : s = _("Shift"); break;
|
||||||
case irr::KEY_MODECHANGE : s = "modechange"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_SPACE : s = "space"; break;
|
case irr::KEY_CONTROL : s = _("Control"); break;
|
||||||
case irr::KEY_PRIOR : s = "page up"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NEXT : s = "page down"; break;
|
case irr::KEY_MENU : s = _("Alt/Menu"); break;
|
||||||
case irr::KEY_END : s = "end"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_HOME : s = "home"; break;
|
case irr::KEY_PAUSE : s = _("Pause"); break;
|
||||||
case irr::KEY_LEFT : s = "left"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_UP : s = "up"; break;
|
case irr::KEY_CAPITAL : s = _("Caps Lock"); break;
|
||||||
case irr::KEY_RIGHT : s = "right"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_DOWN : s = "down"; break;
|
case irr::KEY_KANA : s = _("Kana"); break;
|
||||||
case irr::KEY_SELECT : s = "select"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_PRINT : s = "print"; break;
|
case irr::KEY_JUNJA : s = _("Junja"); break;
|
||||||
case irr::KEY_EXECUT : s = "exec"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_SNAPSHOT : s = "print screen"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_INSERT : s = "insert"; break;
|
case irr::KEY_FINAL : s = _("Final"); break;
|
||||||
case irr::KEY_DELETE : s = "delete"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_HELP : s = "help"; break;
|
case irr::KEY_ESCAPE : s = _("Escape"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_CONVERT : s = _("Convert"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NONCONVERT : s = _("Nonconvert"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_ACCEPT : s = _("Accept"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_MODECHANGE : s = _("Modechange"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_SPACE : s = _("Space"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_PRIOR : s = _("Page Up"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NEXT : s = _("Page Down"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_END : s = _("End"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_HOME : s = _("Home"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_LEFT : s = _("Left"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_UP : s = _("Up"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_RIGHT : s = _("Right"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_DOWN : s = _("Down"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_SELECT : s = _("Select"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_PRINT : s = _("Print"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_EXECUT : s = _("Exec"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_SNAPSHOT : s = _("Print Screen"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_INSERT : s = _("Insert"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_DELETE : s = _("Delete"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_HELP : s = _("Help"); break;
|
||||||
case irr::KEY_KEY_0 : s = "0"; break;
|
case irr::KEY_KEY_0 : s = "0"; break;
|
||||||
case irr::KEY_KEY_1 : s = "1"; break;
|
case irr::KEY_KEY_1 : s = "1"; break;
|
||||||
case irr::KEY_KEY_2 : s = "2"; break;
|
case irr::KEY_KEY_2 : s = "2"; break;
|
||||||
@ -185,26 +225,44 @@ irr::core::stringw Binding::getAsString() const
|
|||||||
case irr::KEY_KEY_X : s = "X"; break;
|
case irr::KEY_KEY_X : s = "X"; break;
|
||||||
case irr::KEY_KEY_Y : s = "Y"; break;
|
case irr::KEY_KEY_Y : s = "Y"; break;
|
||||||
case irr::KEY_KEY_Z : s = "Z"; break;
|
case irr::KEY_KEY_Z : s = "Z"; break;
|
||||||
case irr::KEY_LWIN : s = "Left Logo"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_RWIN : s = "Right Logo"; break;
|
case irr::KEY_LWIN : s = _("Left Logo"); break;
|
||||||
case irr::KEY_APPS : s = "apps"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_SLEEP : s = "sleep"; break;
|
case irr::KEY_RWIN : s = _("Right Logo"); break;
|
||||||
case irr::KEY_NUMPAD0 : s = "numpad 0"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NUMPAD1 : s = "numpad 1"; break;
|
case irr::KEY_APPS : s = _("Apps"); break;
|
||||||
case irr::KEY_NUMPAD2 : s = "numpad 2"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NUMPAD3 : s = "numpad 3"; break;
|
case irr::KEY_SLEEP : s = _("Sleep"); break;
|
||||||
case irr::KEY_NUMPAD4 : s = "numpad 4"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NUMPAD5 : s = "numpad 5"; break;
|
case irr::KEY_NUMPAD0 : s = _("Numpad 0"); break;
|
||||||
case irr::KEY_NUMPAD6 : s = "numpad 6"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NUMPAD7 : s = "numpad 7"; break;
|
case irr::KEY_NUMPAD1 : s = _("Numpad 1"); break;
|
||||||
case irr::KEY_NUMPAD8 : s = "numpad 8"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_NUMPAD9 : s = "numpad 9"; break;
|
case irr::KEY_NUMPAD2 : s = _("Numpad 2"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD3 : s = _("Numpad 3"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD4 : s = _("Numpad 4"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD5 : s = _("Numpad 5"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD6 : s = _("Numpad 6"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD7 : s = _("Numpad 7"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD8 : s = _("Numpad 8"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_NUMPAD9 : s = _("Numpad 9"); break;
|
||||||
case irr::KEY_MULTIPLY : s = "*"; break;
|
case irr::KEY_MULTIPLY : s = "*"; break;
|
||||||
case irr::KEY_ADD : s = "+"; break;
|
case irr::KEY_ADD : s = "+"; break;
|
||||||
case irr::KEY_SEPARATOR : s = "separator"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_SUBTRACT : s = "- (subtract)"; break;
|
case irr::KEY_SEPARATOR : s = _("Separator"); break;
|
||||||
case irr::KEY_DECIMAL : s = "decimal"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_DIVIDE : s = "/ (divide)"; break;
|
case irr::KEY_SUBTRACT : s = _("- (Subtract)"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_DECIMAL : s = _("Decimal"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_DIVIDE : s = _("/ (Divide)"); break;
|
||||||
case irr::KEY_F1 : s = "F1"; break;
|
case irr::KEY_F1 : s = "F1"; break;
|
||||||
case irr::KEY_F2 : s = "F2"; break;
|
case irr::KEY_F2 : s = "F2"; break;
|
||||||
case irr::KEY_F3 : s = "F3"; break;
|
case irr::KEY_F3 : s = "F3"; break;
|
||||||
@ -229,26 +287,42 @@ irr::core::stringw Binding::getAsString() const
|
|||||||
case irr::KEY_F22 : s = "F22"; break;
|
case irr::KEY_F22 : s = "F22"; break;
|
||||||
case irr::KEY_F23 : s = "F23"; break;
|
case irr::KEY_F23 : s = "F23"; break;
|
||||||
case irr::KEY_F24 : s = "F24"; break;
|
case irr::KEY_F24 : s = "F24"; break;
|
||||||
case irr::KEY_NUMLOCK : s = "num lock"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_SCROLL : s = "scroll lock"; break;
|
case irr::KEY_NUMLOCK : s = _("Num Lock"); break;
|
||||||
case irr::KEY_LSHIFT : s = "left shift"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_RSHIFT : s = "right shift"; break;
|
case irr::KEY_SCROLL : s = _("Scroll Lock"); break;
|
||||||
case irr::KEY_LCONTROL : s = "left control"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_RCONTROL : s = "right control"; break;
|
case irr::KEY_LSHIFT : s = _("Left Shift"); break;
|
||||||
case irr::KEY_LMENU : s = "left menu"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_RMENU : s = "right menu"; break;
|
case irr::KEY_RSHIFT : s = _("Right Shift"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_LCONTROL : s = _("Left Control"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_RCONTROL : s = _("Right Control"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_LMENU : s = _("Left Menu"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_RMENU : s = _("Right Menu"); break;
|
||||||
case irr::KEY_PLUS : s = "+"; break;
|
case irr::KEY_PLUS : s = "+"; break;
|
||||||
case irr::KEY_COMMA : s = ","; break;
|
case irr::KEY_COMMA : s = ","; break;
|
||||||
case irr::KEY_MINUS : s = "-"; break;
|
case irr::KEY_MINUS : s = "-"; break;
|
||||||
case irr::KEY_PERIOD : s = "."; break;
|
case irr::KEY_PERIOD : s = "."; break;
|
||||||
case irr::KEY_ATTN : s = "attn"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_CRSEL : s = "crsel"; break;
|
case irr::KEY_ATTN : s = _("Attn"); break;
|
||||||
case irr::KEY_EXSEL : s = "exsel"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_EREOF : s = "ereof"; break;
|
case irr::KEY_CRSEL : s = _("Crsel"); break;
|
||||||
case irr::KEY_PLAY : s = "play"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_ZOOM : s = "zoom"; break;
|
case irr::KEY_EXSEL : s = _("Exsel"); break;
|
||||||
case irr::KEY_PA1 : s = "pa1"; break;
|
//I18N: input configuration screen: keyboard key
|
||||||
case irr::KEY_OEM_CLEAR : s = "oem clear"; break;
|
case irr::KEY_EREOF : s = _("Ereof"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_PLAY : s = _("Play"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_ZOOM : s = _("Zoom"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_PA1 : s = _("Pa1"); break;
|
||||||
|
//I18N: input configuration screen: keyboard key
|
||||||
|
case irr::KEY_OEM_CLEAR : s = _("Oem Clear"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -142,7 +142,7 @@ FileManager::FileManager()
|
|||||||
|
|
||||||
m_file_system = irr::io::createFileSystem();
|
m_file_system = irr::io::createFileSystem();
|
||||||
|
|
||||||
irr::io::path exe_path;
|
std::string exe_path;
|
||||||
|
|
||||||
// Search for the root directory
|
// Search for the root directory
|
||||||
// =============================
|
// =============================
|
||||||
@ -151,8 +151,11 @@ FileManager::FileManager()
|
|||||||
// This is esp. useful for Visual Studio, since it's not necessary
|
// This is esp. useful for Visual Studio, since it's not necessary
|
||||||
// to define the working directory when debugging, it works automatically.
|
// to define the working directory when debugging, it works automatically.
|
||||||
std::string root_dir;
|
std::string root_dir;
|
||||||
if(m_file_system->existFile(CommandLine::getExecName().c_str()))
|
const std::string version = std::string("supertuxkart.") + STK_VERSION;
|
||||||
exe_path = m_file_system->getFileDir(CommandLine::getExecName().c_str());
|
if (fileExists(CommandLine::getExecName()))
|
||||||
|
{
|
||||||
|
exe_path = StringUtils::getPath(CommandLine::getExecName());
|
||||||
|
}
|
||||||
if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/')
|
if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/')
|
||||||
exe_path += "/";
|
exe_path += "/";
|
||||||
if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL )
|
if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL )
|
||||||
@ -160,19 +163,19 @@ FileManager::FileManager()
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; }
|
else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; }
|
||||||
#endif
|
#endif
|
||||||
else if(m_file_system->existFile("data/stk_config.xml"))
|
else if(fileExists("data/", version))
|
||||||
root_dir = "data/" ;
|
root_dir = "data/" ;
|
||||||
else if(m_file_system->existFile("../data/stk_config.xml"))
|
else if(fileExists("../data/", version))
|
||||||
root_dir = "../data/" ;
|
root_dir = "../data/" ;
|
||||||
else if(m_file_system->existFile("../../data/stk_config.xml"))
|
else if(fileExists("../../data/", version))
|
||||||
root_dir = "../../data/" ;
|
root_dir = "../../data/" ;
|
||||||
// Test for old style build environment, with executable in root of stk
|
// Test for old style build environment, with executable in root of stk
|
||||||
else if(m_file_system->existFile(exe_path+"data/stk_config.xml"))
|
else if(fileExists(exe_path+"data/"+version))
|
||||||
root_dir = (exe_path+"data/").c_str();
|
root_dir = (exe_path+"data/").c_str();
|
||||||
// Check for windows cmake style: bld/Debug/bin/supertuxkart.exe
|
// Check for windows cmake style: bld/Debug/bin/supertuxkart.exe
|
||||||
else if (m_file_system->existFile(exe_path + "../../../data/stk_config.xml"))
|
else if (fileExists(exe_path + "../../../data/"+version))
|
||||||
root_dir = (exe_path + "../../../data/").c_str();
|
root_dir = exe_path + "../../../data/";
|
||||||
else if (m_file_system->existFile(exe_path + "../data/stk_config.xml"))
|
else if (fileExists(exe_path + "../data/"+version))
|
||||||
{
|
{
|
||||||
root_dir = exe_path.c_str();
|
root_dir = exe_path.c_str();
|
||||||
root_dir += "../data/";
|
root_dir += "../data/";
|
||||||
@ -181,14 +184,22 @@ FileManager::FileManager()
|
|||||||
{
|
{
|
||||||
#ifdef SUPERTUXKART_DATADIR
|
#ifdef SUPERTUXKART_DATADIR
|
||||||
root_dir = SUPERTUXKART_DATADIR"/data/";
|
root_dir = SUPERTUXKART_DATADIR"/data/";
|
||||||
if(root_dir.size()==0 || root_dir[root_dir.size()-1]!='/')
|
|
||||||
root_dir+='/';
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
root_dir = "/usr/local/share/games/supertuxkart/";
|
root_dir = "/usr/local/share/games/supertuxkart/";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_file_system->existFile((root_dir + version).c_str()))
|
||||||
|
{
|
||||||
|
Log::error("FileManager", "Could not file '%s'in any "
|
||||||
|
"standard location (esp. ../data).", version.c_str());
|
||||||
|
Log::error("FileManager",
|
||||||
|
"Last location checked '%s'.", root_dir.c_str());
|
||||||
|
Log::fatal("FileManager",
|
||||||
|
"Set $SUPERTUXKART_DATADIR to point to the data directory.");
|
||||||
|
// fatal will exit the application
|
||||||
|
}
|
||||||
|
|
||||||
addRootDirs(root_dir);
|
addRootDirs(root_dir);
|
||||||
if( fileExists(root_dir+"../../stk-assets"))
|
if( fileExists(root_dir+"../../stk-assets"))
|
||||||
addRootDirs(root_dir+"../../stk-assets");
|
addRootDirs(root_dir+"../../stk-assets");
|
||||||
|
@ -134,6 +134,14 @@ public:
|
|||||||
std::string searchTexture(const std::string& fname) const;
|
std::string searchTexture(const std::string& fname) const;
|
||||||
std::string getUserConfigFile(const std::string& fname) const;
|
std::string getUserConfigFile(const std::string& fname) const;
|
||||||
bool fileExists(const std::string& path) const;
|
bool fileExists(const std::string& path) const;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Convenience function to save some typing in the
|
||||||
|
* file manager constructor. */
|
||||||
|
bool fileExists(const char *prefix, const std::string& path) const
|
||||||
|
{
|
||||||
|
return fileExists(std::string(prefix) + path);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
void listFiles (std::set<std::string>& result,
|
void listFiles (std::set<std::string>& result,
|
||||||
const std::string& dir,
|
const std::string& dir,
|
||||||
bool make_full_path=false) const;
|
bool make_full_path=false) const;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "items/flyable.hpp"
|
#include "items/flyable.hpp"
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
|
||||||
#include <IMeshManipulator.h>
|
#include <IMeshManipulator.h>
|
||||||
#include <IMeshSceneNode.h>
|
#include <IMeshSceneNode.h>
|
||||||
|
@ -109,11 +109,8 @@ ExplosionAnimation::ExplosionAnimation(AbstractKart *kart,
|
|||||||
float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime() *
|
float t = m_kart->getKartProperties()->getExplosionInvulnerabilityTime() *
|
||||||
m_kart->getPlayerDifficulty()->getExplosionInvulnerabilityTime();
|
m_kart->getPlayerDifficulty()->getExplosionInvulnerabilityTime();
|
||||||
m_kart->setInvulnerableTime(t);
|
m_kart->setInvulnerableTime(t);
|
||||||
if ( UserConfigParams::m_graphical_effects )
|
m_kart->showStarEffect(t);
|
||||||
{
|
|
||||||
m_kart->showStarEffect(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_kart->getAttachment()->clear();
|
m_kart->getAttachment()->clear();
|
||||||
|
|
||||||
}; // ExplosionAnimation
|
}; // ExplosionAnimation
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
|
|
||||||
#include <algorithm> // for min and max
|
#include <algorithm> // for min and max
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||||
@ -1077,11 +1077,8 @@ void Kart::update(float dt)
|
|||||||
m_max_speed->getCurrentMaxSpeed());
|
m_max_speed->getCurrentMaxSpeed());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( UserConfigParams::m_graphical_effects )
|
// update star effect (call will do nothing if stars are not activated)
|
||||||
{
|
m_stars_effect->update(dt);
|
||||||
// update star effect (call will do nothing if stars are not activated)
|
|
||||||
m_stars_effect->update(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_squash_time>=0)
|
if(m_squash_time>=0)
|
||||||
{
|
{
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp
|
|
||||||
index de14bbe..47bbee9 100644
|
|
||||||
--- a/src/karts/kart.cpp
|
|
||||||
+++ b/src/karts/kart.cpp
|
|
||||||
@@ -2476,11 +2476,12 @@ void Kart::kartIsInRestNow()
|
|
||||||
for(int i=0; i<m_vehicle->getNumWheels(); i++)
|
|
||||||
{
|
|
||||||
const btWheelInfo &wi = m_vehicle->getWheelInfo(i);
|
|
||||||
- f += wi.m_chassisConnectionPointCS.getY()
|
|
||||||
- - wi.m_raycastInfo.m_suspensionLength - wi.m_wheelsRadius;
|
|
||||||
+ f += wi.m_raycastInfo.m_suspensionLength;
|
|
||||||
}
|
|
||||||
+ m_terrain_info->update(getTrans());
|
|
||||||
m_graphical_y_offset = f/m_vehicle->getNumWheels()
|
|
||||||
+ getKartProperties()->getGraphicalYOffset();
|
|
||||||
+ m_graphical_y_offset = m_kart_model->getLowestPoint() - (getXYZ().getY() - m_terrain_info->getHoT());
|
|
||||||
|
|
||||||
m_kart_model->setDefaultSuspension();
|
|
||||||
} // kartIsInRestNow
|
|
||||||
@@ -2595,11 +2596,6 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
|
||||||
} // for i<num_wheels
|
|
||||||
const btWheelInfo &w = getVehicle()->getWheelInfo(0);
|
|
||||||
|
|
||||||
- // Determine the shadow position from the terrain Y position. This
|
|
||||||
- // leaves the shadow on the ground even if the kart is jumping because
|
|
||||||
- // of skidding (shadows are disabled when wheel are not on the track).
|
|
||||||
- m_shadow->update(m_terrain_info->getHoT() - getXYZ().getY()
|
|
||||||
- -m_skidding->getGraphicalJumpOffset());
|
|
||||||
// Recompute the default average suspension length, see
|
|
||||||
// kartIsInRestNow() how to get from y-offset to susp. len.
|
|
||||||
float av_sus_len = -m_graphical_y_offset
|
|
||||||
@@ -2628,6 +2624,9 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
|
||||||
+ lean_height
|
|
||||||
- m_kart_model->getLowestPoint());
|
|
||||||
|
|
||||||
+ center_shift.setY(m_skidding->getGraphicalJumpOffset()
|
|
||||||
+ + lean_height
|
|
||||||
+ +m_graphical_y_offset);
|
|
||||||
center_shift = getTrans().getBasis() * center_shift;
|
|
||||||
|
|
||||||
Moveable::updateGraphics(dt, center_shift,
|
|
||||||
@@ -2637,6 +2636,14 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
|
||||||
// how much the wheels need to rotate.
|
|
||||||
m_kart_model->update(dt, m_speed*dt, getSteerPercent(), m_speed);
|
|
||||||
|
|
||||||
+ // Determine the shadow position from the terrain Y position. This
|
|
||||||
+ // leaves the shadow on the ground even if the kart is jumping because
|
|
||||||
+ // of skidding (shadows are disabled when wheel are not on the track).
|
|
||||||
+ m_shadow->update( m_terrain_info->getHoT() - getXYZ().getY()
|
|
||||||
+ - m_skidding->getGraphicalJumpOffset()
|
|
||||||
+ - m_graphical_y_offset
|
|
||||||
+ - m_kart_model->getLowestPoint());
|
|
||||||
+
|
|
||||||
#ifdef XX
|
|
||||||
// cheap wheelie effect
|
|
||||||
if (m_controls.m_nitro)
|
|
||||||
diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp
|
|
||||||
index 65879d3..36b03b7 100644
|
|
||||||
--- a/src/karts/kart_model.cpp
|
|
||||||
+++ b/src/karts/kart_model.cpp
|
|
||||||
@@ -813,7 +813,9 @@ void KartModel::update(float dt, float distance, float steer, float speed)
|
|
||||||
core::vector3df pos = m_wheel_graphics_position[i].toIrrVector();
|
|
||||||
|
|
||||||
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(i);
|
|
||||||
- pos.Y = -wi.m_raycastInfo.m_suspensionLength + m_wheel_graphics_radius[i] + getLowestPoint();
|
|
||||||
+ pos.Y += m_default_physics_suspension[i]
|
|
||||||
+ - wi.m_raycastInfo.m_suspensionLength
|
|
||||||
+ - getLowestPoint();
|
|
||||||
m_wheel_node[i]->setPosition(pos);
|
|
||||||
|
|
||||||
// Now calculate the new rotation: (old + change) mod 360
|
|
@ -1078,7 +1078,7 @@ int handleCmdLine()
|
|||||||
void initUserConfig()
|
void initUserConfig()
|
||||||
{
|
{
|
||||||
file_manager = new FileManager();
|
file_manager = new FileManager();
|
||||||
user_config = new UserConfig(); // needs file_manager
|
user_config = new UserConfig(); // needs file_manager
|
||||||
user_config->loadConfig();
|
user_config->loadConfig();
|
||||||
// Some parts of the file manager needs user config (paths for models
|
// Some parts of the file manager needs user config (paths for models
|
||||||
// depend on artist debug flag). So init the rest of the file manager
|
// depend on artist debug flag). So init the rest of the file manager
|
||||||
|
@ -77,13 +77,8 @@ void CutsceneWorld::init()
|
|||||||
|
|
||||||
m_duration = -1.0f;
|
m_duration = -1.0f;
|
||||||
|
|
||||||
//const btTransform &s = getTrack()->getStartTransform(0);
|
|
||||||
//const Vec3 &v = s.getOrigin();
|
|
||||||
Camera* stk_cam = Camera::createCamera(NULL);
|
Camera* stk_cam = Camera::createCamera(NULL);
|
||||||
m_camera = stk_cam->getCameraSceneNode();
|
m_camera = stk_cam->getCameraSceneNode();
|
||||||
//m_camera = irr_driver->getSceneManager()
|
|
||||||
// ->addCameraSceneNode(NULL, core::vector3df(0.0f, 0.0f, 0.0f),
|
|
||||||
// core::vector3df(0.0f, 0.0f, 0.0f));
|
|
||||||
m_camera->setFOV(0.61f);
|
m_camera->setFOV(0.61f);
|
||||||
m_camera->bindTargetAndRotation(true); // no "look-at"
|
m_camera->bindTargetAndRotation(true); // no "look-at"
|
||||||
|
|
||||||
|
@ -53,9 +53,13 @@ FollowTheLeaderRace::FollowTheLeaderRace() : LinearWorld()
|
|||||||
*/
|
*/
|
||||||
void FollowTheLeaderRace::init()
|
void FollowTheLeaderRace::init()
|
||||||
{
|
{
|
||||||
|
m_last_eliminated_time = 0;
|
||||||
LinearWorld::init();
|
LinearWorld::init();
|
||||||
|
// WorldWithRank determines the score based on getNumKarts(), but since
|
||||||
|
// we ignore the leader, the points need to be based on number of karts -1
|
||||||
|
stk_config->getAllScores(&m_score_for_position, getNumKarts() - 1);
|
||||||
getKart(0)->setOnScreenText(_("Leader"));
|
getKart(0)->setOnScreenText(_("Leader"));
|
||||||
}
|
} // init
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
@ -83,11 +87,37 @@ void FollowTheLeaderRace::reset()
|
|||||||
m_is_over_delay = 2.0f;
|
m_is_over_delay = 2.0f;
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the number of points for a kart at a specified position.
|
||||||
|
* \param p Position (starting with 1).
|
||||||
|
*/
|
||||||
|
int FollowTheLeaderRace::getScoreForPosition(int p)
|
||||||
|
{
|
||||||
|
// Kart 0 (the leader) does not get any points
|
||||||
|
if (p == 1) return 0;
|
||||||
|
|
||||||
|
assert(p-2 >= 0);
|
||||||
|
assert(p - 2 <(int) m_score_for_position.size());
|
||||||
|
return m_score_for_position[p - 2];
|
||||||
|
} // getScoreForPosition
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
const btTransform &FollowTheLeaderRace::getStartTransform(int index)
|
||||||
|
{
|
||||||
|
if (index == 0) // Leader start position
|
||||||
|
return m_track->getStartTransform(index);
|
||||||
|
|
||||||
|
// Otherwise the karts will start at the rear starting positions
|
||||||
|
int start_index = stk_config->m_max_karts
|
||||||
|
- race_manager->getNumberOfKarts() + index;
|
||||||
|
return m_track->getStartTransform(start_index);
|
||||||
|
} // getStartTransform
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Returns the original time at which the countdown timer started. This is
|
/** Returns the original time at which the countdown timer started. This is
|
||||||
* used by the race_gui to display the music credits in FTL mode correctly.
|
* used by the race_gui to display the music credits in FTL mode correctly.
|
||||||
*/
|
*/
|
||||||
float FollowTheLeaderRace::getClockStartTime()
|
float FollowTheLeaderRace::getClockStartTime() const
|
||||||
{
|
{
|
||||||
return m_leader_intervals[0];
|
return m_leader_intervals[0];
|
||||||
} // getClockStartTime
|
} // getClockStartTime
|
||||||
@ -97,6 +127,7 @@ float FollowTheLeaderRace::getClockStartTime()
|
|||||||
*/
|
*/
|
||||||
void FollowTheLeaderRace::countdownReachedZero()
|
void FollowTheLeaderRace::countdownReachedZero()
|
||||||
{
|
{
|
||||||
|
m_last_eliminated_time += m_leader_intervals[0];
|
||||||
if(m_leader_intervals.size()>1)
|
if(m_leader_intervals.size()>1)
|
||||||
m_leader_intervals.erase(m_leader_intervals.begin());
|
m_leader_intervals.erase(m_leader_intervals.begin());
|
||||||
WorldStatus::setTime(m_leader_intervals[0]);
|
WorldStatus::setTime(m_leader_intervals[0]);
|
||||||
@ -145,7 +176,7 @@ void FollowTheLeaderRace::countdownReachedZero()
|
|||||||
updateRacePosition();
|
updateRacePosition();
|
||||||
}
|
}
|
||||||
// Time doesn't make any sense in FTL (and it is not displayed)
|
// Time doesn't make any sense in FTL (and it is not displayed)
|
||||||
kart->finishedRace(-1.0f);
|
kart->finishedRace(m_last_eliminated_time);
|
||||||
|
|
||||||
// Move any camera for this kart to the leader, facing backwards,
|
// Move any camera for this kart to the leader, facing backwards,
|
||||||
// so that the eliminated player has something to watch.
|
// so that the eliminated player has something to watch.
|
||||||
@ -169,43 +200,6 @@ void FollowTheLeaderRace::countdownReachedZero()
|
|||||||
music_manager->switchToFastMusic();
|
music_manager->switchToFastMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRaceOver())
|
|
||||||
{
|
|
||||||
// Handle special FTL situation: the leader is kart number 3 when
|
|
||||||
// the last kart gets eliminated. In this case kart on position 1
|
|
||||||
// is eliminated, and the kart formerly on position 2 is on
|
|
||||||
// position 1, the leader now position 2. In this case the kart
|
|
||||||
// on position 1 would get more points for this victory. So if
|
|
||||||
// this is the case, change the position
|
|
||||||
if(m_karts[0]->getPosition()!=1)
|
|
||||||
{
|
|
||||||
// Adjust the position of all still driving karts that
|
|
||||||
// are ahead of the leader by +1, and move the leader
|
|
||||||
// to position 1.
|
|
||||||
for (unsigned int i=1; i<m_karts.size(); i++)
|
|
||||||
{
|
|
||||||
if(!m_karts[i]->hasFinishedRace() &&
|
|
||||||
!m_karts[i]->isEliminated() &&
|
|
||||||
m_karts[i]->getPosition()<m_karts[0]->getPosition())
|
|
||||||
{
|
|
||||||
m_karts[i]->setPosition(m_karts[i]->getPosition()+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_karts[0]->setPosition(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark all still racing karts to be finished.
|
|
||||||
for (unsigned int n=0; n<m_karts.size(); n++)
|
|
||||||
{
|
|
||||||
if (!m_karts[n]->isEliminated() &&
|
|
||||||
!m_karts[n]->hasFinishedRace())
|
|
||||||
{
|
|
||||||
m_karts[n]->finishedRace(getTime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// End of race is detected from World::updateWorld()
|
|
||||||
|
|
||||||
} // countdownReachedZero
|
} // countdownReachedZero
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -233,6 +227,53 @@ bool FollowTheLeaderRace::isRaceOver()
|
|||||||
}
|
}
|
||||||
} // isRaceOver
|
} // isRaceOver
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Called at the end of a race. Updates highscores, pauses the game, and
|
||||||
|
* informs the unlock manager about the finished race. This function must
|
||||||
|
* be called after all other stats were updated from the different game
|
||||||
|
* modes.
|
||||||
|
*/
|
||||||
|
void FollowTheLeaderRace::terminateRace()
|
||||||
|
{
|
||||||
|
int pos_leader = m_karts[0]->getPosition();
|
||||||
|
|
||||||
|
// Handle special FTL situations: the leader is kart number 3 when
|
||||||
|
// the last kart gets eliminated. In this case kart on position 1
|
||||||
|
// is eliminated, and the kart formerly on position 2 is on
|
||||||
|
// position 1, the leader now position 2, but the point distribution
|
||||||
|
// depends on the 'first' (non-leader) kart to be on position 2.
|
||||||
|
// That situation can also occur during the delay after eliminating
|
||||||
|
// the last kart before the race result is shown (when the leader
|
||||||
|
// is overtaken during that time). To avoid this problem, adjust the
|
||||||
|
// position of any kart that is ahead of the leader.
|
||||||
|
beginSetKartPositions();
|
||||||
|
for (unsigned int i = 0; i < getNumKarts(); i++)
|
||||||
|
{
|
||||||
|
if (!m_karts[i]->hasFinishedRace() && !m_karts[i]->isEliminated() &&
|
||||||
|
m_karts[i]->getPosition() < pos_leader)
|
||||||
|
{
|
||||||
|
setKartPosition(i, m_karts[i]->getPosition() + 1);
|
||||||
|
}
|
||||||
|
} // i < number of karts
|
||||||
|
setKartPosition(/*kart id*/0, /*position*/1);
|
||||||
|
endSetKartPositions();
|
||||||
|
|
||||||
|
// Mark all still racing karts to be finished.
|
||||||
|
for (int i = m_karts.size(); i>0; i--)
|
||||||
|
{
|
||||||
|
AbstractKart *kart = getKartAtPosition(i);
|
||||||
|
if (kart->isEliminated() || kart->hasFinishedRace())
|
||||||
|
continue;
|
||||||
|
m_last_eliminated_time += m_leader_intervals[0];
|
||||||
|
if (m_leader_intervals.size() > 1)
|
||||||
|
m_leader_intervals.erase(m_leader_intervals.begin());
|
||||||
|
kart->finishedRace(m_last_eliminated_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
World::terminateRace();
|
||||||
|
} // terminateRace
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Returns the internal identifier for this kind of race.
|
/** Returns the internal identifier for this kind of race.
|
||||||
*/
|
*/
|
||||||
|
@ -27,9 +27,15 @@
|
|||||||
class FollowTheLeaderRace : public LinearWorld
|
class FollowTheLeaderRace : public LinearWorld
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<float> m_leader_intervals; // time till elimination in follow leader
|
// time till elimination in follow leader
|
||||||
float m_is_over_delay; //!< A timer used before terminating the race
|
std::vector<float> m_leader_intervals;
|
||||||
|
|
||||||
|
/** A timer used before terminating the race. */
|
||||||
|
float m_is_over_delay;
|
||||||
|
|
||||||
|
/** Time the last kart was eliminated. It is used to assign each
|
||||||
|
* kart a 'finish' time (i.e. how long they lasted). */
|
||||||
|
float m_last_eliminated_time;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FollowTheLeaderRace();
|
FollowTheLeaderRace();
|
||||||
@ -37,19 +43,24 @@ public:
|
|||||||
|
|
||||||
// clock events
|
// clock events
|
||||||
virtual void countdownReachedZero() OVERRIDE;
|
virtual void countdownReachedZero() OVERRIDE;
|
||||||
|
virtual int getScoreForPosition(int p) OVERRIDE;
|
||||||
|
|
||||||
// overriding World methods
|
// overriding World methods
|
||||||
virtual void reset() OVERRIDE;
|
virtual void reset() OVERRIDE;
|
||||||
virtual const std::string& getIdent() const OVERRIDE;
|
virtual const std::string& getIdent() const OVERRIDE;
|
||||||
virtual float getClockStartTime();
|
virtual const btTransform &getStartTransform(int index);
|
||||||
virtual bool useFastMusicNearEnd() const OVERRIDE { return false; }
|
virtual float getClockStartTime() const;
|
||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||||
virtual void init() OVERRIDE;
|
virtual void init() OVERRIDE;
|
||||||
|
virtual void terminateRace() OVERRIDE;
|
||||||
virtual bool isRaceOver() OVERRIDE;
|
virtual bool isRaceOver() OVERRIDE;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns if this type of race has laps. */
|
||||||
virtual bool raceHasLaps() OVERRIDE { return false; }
|
virtual bool raceHasLaps() OVERRIDE { return false; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns if faster music should be used at the end. */
|
||||||
|
virtual bool useFastMusicNearEnd() const OVERRIDE { return false; }
|
||||||
}; // FollowTheLeader
|
}; // FollowTheLeader
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,6 +160,37 @@ void OverWorld::update(float dt)
|
|||||||
}
|
}
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Finds the starting position which is closest to the kart.
|
||||||
|
* \param kart The kart for which a rescue position needs to be determined.
|
||||||
|
*/
|
||||||
|
unsigned int OverWorld::getRescuePositionIndex(AbstractKart *kart)
|
||||||
|
{
|
||||||
|
// find closest point to drop kart on
|
||||||
|
const int start_spots_amount = getNumberOfRescuePositions();
|
||||||
|
assert(start_spots_amount > 0);
|
||||||
|
|
||||||
|
int closest_id = -1;
|
||||||
|
float closest_distance = 999999999.0f;
|
||||||
|
|
||||||
|
for (int n=0; n<start_spots_amount; n++)
|
||||||
|
{
|
||||||
|
const btTransform &s = getStartTransform(n);
|
||||||
|
const Vec3 &v = s.getOrigin();
|
||||||
|
|
||||||
|
float abs_distance = (v - kart->getXYZ()).length();
|
||||||
|
|
||||||
|
if (abs_distance < closest_distance)
|
||||||
|
{
|
||||||
|
closest_distance = abs_distance;
|
||||||
|
closest_id = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(closest_id != -1);
|
||||||
|
return closest_id;
|
||||||
|
} // getRescuePositionIndex
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** This function is not used in the overworld race gui.
|
/** This function is not used in the overworld race gui.
|
||||||
*/
|
*/
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
static void enterOverWorld();
|
static void enterOverWorld();
|
||||||
|
|
||||||
virtual void update(float delta) OVERRIDE;
|
virtual void update(float delta) OVERRIDE;
|
||||||
|
unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE;
|
||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -108,7 +108,7 @@ AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index,
|
|||||||
RaceManager::KartType type,
|
RaceManager::KartType type,
|
||||||
const PlayerDifficulty *difficulty)
|
const PlayerDifficulty *difficulty)
|
||||||
{
|
{
|
||||||
btTransform init_pos = m_track->getStartTransform(index);
|
btTransform init_pos = getStartTransform(index);
|
||||||
|
|
||||||
Kart *new_kart = new KartWithStats(kart_ident,
|
Kart *new_kart = new KartWithStats(kart_ident,
|
||||||
/*world kart id*/ index,
|
/*world kart id*/ index,
|
||||||
|
@ -315,88 +315,6 @@ void SoccerWorld::getKartsDisplayInfo(
|
|||||||
*/
|
*/
|
||||||
} // getKartsDisplayInfo
|
} // getKartsDisplayInfo
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** Moves a kart to its rescue position.
|
|
||||||
* \param kart The kart that was rescued.
|
|
||||||
*/
|
|
||||||
void SoccerWorld::moveKartAfterRescue(AbstractKart* kart)
|
|
||||||
{
|
|
||||||
// find closest point to drop kart on
|
|
||||||
World *world = World::getWorld();
|
|
||||||
const int start_spots_amount = world->getTrack()->getNumberOfStartPositions();
|
|
||||||
assert(start_spots_amount > 0);
|
|
||||||
|
|
||||||
float largest_accumulated_distance_found = -1;
|
|
||||||
int furthest_id_found = -1;
|
|
||||||
|
|
||||||
const float kart_x = kart->getXYZ().getX();
|
|
||||||
const float kart_z = kart->getXYZ().getZ();
|
|
||||||
|
|
||||||
for(int n=0; n<start_spots_amount; n++)
|
|
||||||
{
|
|
||||||
// no need for the overhead to compute exact distance with sqrt(),
|
|
||||||
// so using the 'manhattan' heuristic which will do fine enough.
|
|
||||||
const btTransform &s = world->getTrack()->getStartTransform(n);
|
|
||||||
const Vec3 &v=s.getOrigin();
|
|
||||||
float accumulatedDistance = .0f;
|
|
||||||
bool spawnPointClear = true;
|
|
||||||
|
|
||||||
for(unsigned int k=0; k<getCurrentNumKarts(); k++)
|
|
||||||
{
|
|
||||||
const AbstractKart *currentKart = World::getWorld()->getKart(k);
|
|
||||||
const float currentKart_x = currentKart->getXYZ().getX();
|
|
||||||
const float currentKartk_z = currentKart->getXYZ().getZ();
|
|
||||||
|
|
||||||
if(kart_x!=currentKart_x && kart_z !=currentKartk_z)
|
|
||||||
{
|
|
||||||
float absDistance = fabs(currentKart_x - v.getX()) +
|
|
||||||
fabs(currentKartk_z - v.getZ());
|
|
||||||
if(absDistance < CLEAR_SPAWN_RANGE)
|
|
||||||
{
|
|
||||||
spawnPointClear = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
accumulatedDistance += absDistance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(largest_accumulated_distance_found < accumulatedDistance && spawnPointClear)
|
|
||||||
{
|
|
||||||
furthest_id_found = n;
|
|
||||||
largest_accumulated_distance_found = accumulatedDistance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(furthest_id_found != -1);
|
|
||||||
const btTransform &s = world->getTrack()->getStartTransform(furthest_id_found);
|
|
||||||
const Vec3 &xyz = s.getOrigin();
|
|
||||||
kart->setXYZ(xyz);
|
|
||||||
kart->setRotation(s.getRotation());
|
|
||||||
|
|
||||||
//position kart from same height as in World::resetAllKarts
|
|
||||||
btTransform pos;
|
|
||||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f));
|
|
||||||
pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) );
|
|
||||||
|
|
||||||
kart->getBody()->setCenterOfMassTransform(pos);
|
|
||||||
|
|
||||||
//project kart to surface of track
|
|
||||||
bool kart_over_ground = m_track->findGround(kart);
|
|
||||||
|
|
||||||
if (kart_over_ground)
|
|
||||||
{
|
|
||||||
//add vertical offset so that the kart starts off above the track
|
|
||||||
float vertical_offset = kart->getKartProperties()->getVertRescueOffset() *
|
|
||||||
kart->getKartHeight();
|
|
||||||
kart->getBody()->translate(btVector3(0, vertical_offset, 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log::warn("[SoccerWorld]", " Invalid position after rescue for kart %s on track %s.",
|
|
||||||
kart->getIdent().c_str(), m_track->getIdent().c_str());
|
|
||||||
}
|
|
||||||
} // moveKartAfterRescue
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Set position and team for the karts */
|
/** Set position and team for the karts */
|
||||||
void SoccerWorld::initKartList()
|
void SoccerWorld::initKartList()
|
||||||
@ -481,7 +399,7 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
|
|||||||
if(index % 2 != 0) posIndex += 1;
|
if(index % 2 != 0) posIndex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
btTransform init_pos = m_track->getStartTransform(posIndex);
|
btTransform init_pos = getStartTransform(posIndex);
|
||||||
|
|
||||||
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
|
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
|
||||||
difficulty);
|
difficulty);
|
||||||
|
@ -76,8 +76,7 @@ public:
|
|||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||||
int getScore(unsigned int i);
|
int getScore(unsigned int i);
|
||||||
virtual bool raceHasLaps(){ return false; }
|
virtual bool raceHasLaps() { return false; }
|
||||||
virtual void moveKartAfterRescue(AbstractKart* kart);
|
|
||||||
|
|
||||||
virtual const std::string& getIdent() const;
|
virtual const std::string& getIdent() const;
|
||||||
|
|
||||||
|
@ -477,53 +477,3 @@ void ThreeStrikesBattle::getKartsDisplayInfo(
|
|||||||
}
|
}
|
||||||
} // getKartsDisplayInfo
|
} // getKartsDisplayInfo
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
/** Determines the rescue position for a kart. The rescue position is the
|
|
||||||
* start position which is has the biggest accumulated distance to all other
|
|
||||||
* karts, and which has no other kart very close. The latter avoids dropping
|
|
||||||
* a kart on top of another kart.
|
|
||||||
* \param kart The kart that is going to be rescued.
|
|
||||||
* \returns The index of the start position to which the rescued kart
|
|
||||||
* should be moved to.
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned int ThreeStrikesBattle::getRescuePositionIndex(AbstractKart *kart)
|
|
||||||
{
|
|
||||||
const int start_spots_amount = getTrack()->getNumberOfStartPositions();
|
|
||||||
assert(start_spots_amount > 0);
|
|
||||||
|
|
||||||
float largest_accumulated_distance_found = -1;
|
|
||||||
int furthest_id_found = -1;
|
|
||||||
|
|
||||||
for(int n=0; n<start_spots_amount; n++)
|
|
||||||
{
|
|
||||||
const btTransform &s = getTrack()->getStartTransform(n);
|
|
||||||
const Vec3 &v=s.getOrigin();
|
|
||||||
float accumulated_distance = .0f;
|
|
||||||
bool spawn_point_clear = true;
|
|
||||||
|
|
||||||
for(unsigned int k=0; k<getCurrentNumKarts(); k++)
|
|
||||||
{
|
|
||||||
if(kart->getWorldKartId()==k) continue;
|
|
||||||
float abs_distance2 = (getKart(k)->getXYZ()-v).length2_2d();
|
|
||||||
const float CLEAR_SPAWN_RANGE2 = 5*5;
|
|
||||||
if( abs_distance2 < CLEAR_SPAWN_RANGE2)
|
|
||||||
{
|
|
||||||
spawn_point_clear = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
accumulated_distance += sqrt(abs_distance2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(accumulated_distance > largest_accumulated_distance_found &&
|
|
||||||
spawn_point_clear)
|
|
||||||
{
|
|
||||||
furthest_id_found = n;
|
|
||||||
largest_accumulated_distance_found = accumulated_distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(furthest_id_found != -1);
|
|
||||||
return furthest_id_found;
|
|
||||||
} // getRescuePositionIndex
|
|
||||||
|
|
||||||
|
@ -97,7 +97,6 @@ public:
|
|||||||
virtual void getKartsDisplayInfo(
|
virtual void getKartsDisplayInfo(
|
||||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||||
virtual bool raceHasLaps(){ return false; }
|
virtual bool raceHasLaps(){ return false; }
|
||||||
virtual unsigned int getRescuePositionIndex(AbstractKart *kart);
|
|
||||||
|
|
||||||
virtual const std::string& getIdent() const;
|
virtual const std::string& getIdent() const;
|
||||||
|
|
||||||
|
@ -305,9 +305,9 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
|
|||||||
const PlayerDifficulty *difficulty)
|
const PlayerDifficulty *difficulty)
|
||||||
{
|
{
|
||||||
int position = index+1;
|
int position = index+1;
|
||||||
btTransform init_pos = m_track->getStartTransform(index);
|
btTransform init_pos = getStartTransform(index);
|
||||||
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
|
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
|
||||||
difficulty);
|
difficulty);
|
||||||
new_kart->init(race_manager->getKartType(index));
|
new_kart->init(race_manager->getKartType(index));
|
||||||
Controller *controller = NULL;
|
Controller *controller = NULL;
|
||||||
switch(kart_type)
|
switch(kart_type)
|
||||||
@ -337,6 +337,14 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
|
|||||||
return new_kart;
|
return new_kart;
|
||||||
} // createKart
|
} // createKart
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the start coordinates for a kart with a given index.
|
||||||
|
* \param index Index of kart ranging from 0 to kart_num-1. */
|
||||||
|
const btTransform &World::getStartTransform(int index)
|
||||||
|
{
|
||||||
|
return m_track->getStartTransform(index);
|
||||||
|
} // getStartTransform
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Creates an AI controller for the kart.
|
/** Creates an AI controller for the kart.
|
||||||
* \param kart The kart to be controlled by an AI.
|
* \param kart The kart to be controlled by an AI.
|
||||||
|
@ -231,7 +231,7 @@ public:
|
|||||||
/** Returns the bullet transformation for the specified rescue index. */
|
/** Returns the bullet transformation for the specified rescue index. */
|
||||||
virtual btTransform getRescueTransform(unsigned int index) const = 0;
|
virtual btTransform getRescueTransform(unsigned int index) const = 0;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void moveKartAfterRescue(AbstractKart* kart);
|
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Called when it is needed to know whether this kind of race involves
|
/** Called when it is needed to know whether this kind of race involves
|
||||||
* counting laps. */
|
* counting laps. */
|
||||||
@ -294,6 +294,7 @@ public:
|
|||||||
PhysicalObject *object);
|
PhysicalObject *object);
|
||||||
AbstractKart* getPlayerKart(unsigned int player) const;
|
AbstractKart* getPlayerKart(unsigned int player) const;
|
||||||
AbstractKart* getLocalPlayerKart(unsigned int n) const;
|
AbstractKart* getLocalPlayerKart(unsigned int n) const;
|
||||||
|
virtual const btTransform &getStartTransform(int index);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns a pointer to the race gui. */
|
/** Returns a pointer to the race gui. */
|
||||||
RaceGUIBase *getRaceGUI() const { return m_race_gui;}
|
RaceGUIBase *getRaceGUI() const { return m_race_gui;}
|
||||||
|
@ -37,6 +37,8 @@ void WorldWithRank::init()
|
|||||||
m_position_used.resize(m_karts.size());
|
m_position_used.resize(m_karts.size());
|
||||||
m_position_setting_initialised = false;
|
m_position_setting_initialised = false;
|
||||||
#endif
|
#endif
|
||||||
|
stk_config->getAllScores(&m_score_for_position, getNumKarts());
|
||||||
|
|
||||||
} // init
|
} // init
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -132,35 +134,54 @@ unsigned int WorldWithRank::getNumberOfRescuePositions() const
|
|||||||
return getTrack()->getNumberOfStartPositions();
|
return getTrack()->getNumberOfStartPositions();
|
||||||
} // getNumberOfRescuePositions
|
} // getNumberOfRescuePositions
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Finds the starting position which is closest to the kart.
|
/** Determines the rescue position for a kart. The rescue position is the
|
||||||
* \param kart The kart for which a rescue position needs to be determined.
|
* start position which is has the biggest accumulated distance to all other
|
||||||
|
* karts, and which has no other kart very close. The latter avoids dropping
|
||||||
|
* a kart on top of another kart. This is the method used
|
||||||
|
* \param kart The kart that is going to be rescued.
|
||||||
|
* \returns The index of the start position to which the rescued kart
|
||||||
|
* should be moved to.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned int WorldWithRank::getRescuePositionIndex(AbstractKart *kart)
|
unsigned int WorldWithRank::getRescuePositionIndex(AbstractKart *kart)
|
||||||
{
|
{
|
||||||
// find closest point to drop kart on
|
const int start_spots_amount = getTrack()->getNumberOfStartPositions();
|
||||||
const int start_spots_amount = getNumberOfRescuePositions();
|
|
||||||
assert(start_spots_amount > 0);
|
assert(start_spots_amount > 0);
|
||||||
|
|
||||||
int closest_id = -1;
|
float largest_accumulated_distance_found = -1;
|
||||||
float closest_distance = 999999999.0f;
|
int furthest_id_found = -1;
|
||||||
|
|
||||||
for (int n=0; n<start_spots_amount; n++)
|
for(int n=0; n<start_spots_amount; n++)
|
||||||
{
|
{
|
||||||
const btTransform &s = getTrack()->getStartTransform(n);
|
const btTransform &s = getStartTransform(n);
|
||||||
const Vec3 &v = s.getOrigin();
|
const Vec3 &v=s.getOrigin();
|
||||||
|
float accumulated_distance = .0f;
|
||||||
|
bool spawn_point_clear = true;
|
||||||
|
|
||||||
float abs_distance = (v - kart->getXYZ()).length();
|
for(unsigned int k=0; k<getCurrentNumKarts(); k++)
|
||||||
|
|
||||||
if (abs_distance < closest_distance)
|
|
||||||
{
|
{
|
||||||
closest_distance = abs_distance;
|
if(kart->getWorldKartId()==k) continue;
|
||||||
closest_id = n;
|
float abs_distance2 = (getKart(k)->getXYZ()-v).length2_2d();
|
||||||
|
const float CLEAR_SPAWN_RANGE2 = 5*5;
|
||||||
|
if( abs_distance2 < CLEAR_SPAWN_RANGE2)
|
||||||
|
{
|
||||||
|
spawn_point_clear = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
accumulated_distance += sqrt(abs_distance2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(accumulated_distance > largest_accumulated_distance_found &&
|
||||||
|
spawn_point_clear)
|
||||||
|
{
|
||||||
|
furthest_id_found = n;
|
||||||
|
largest_accumulated_distance_found = accumulated_distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(closest_id != -1);
|
assert(furthest_id_found != -1);
|
||||||
return closest_id;
|
return furthest_id_found;
|
||||||
} // getRescuePositionIndex
|
} // getRescuePositionIndex
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -173,3 +194,13 @@ btTransform WorldWithRank::getRescueTransform(unsigned int rescue_pos) const
|
|||||||
return getTrack()->getStartTransform(rescue_pos);
|
return getTrack()->getStartTransform(rescue_pos);
|
||||||
} // getRescueTransform
|
} // getRescueTransform
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Returns the number of points for a kart at a specified position.
|
||||||
|
* \param p Position (starting with 1).
|
||||||
|
*/
|
||||||
|
int WorldWithRank::getScoreForPosition(int p)
|
||||||
|
{
|
||||||
|
assert(p-1 >= 0);
|
||||||
|
assert(p - 1 <(int) m_score_for_position.size());
|
||||||
|
return m_score_for_position[p - 1];
|
||||||
|
} // getScoreForPosition
|
||||||
|
@ -43,6 +43,10 @@ protected:
|
|||||||
/** Whether to display the rank in the race GUI */
|
/** Whether to display the rank in the race GUI */
|
||||||
bool m_display_rank;
|
bool m_display_rank;
|
||||||
|
|
||||||
|
/** The points given to a kart on a given position (index is
|
||||||
|
* 0 based, so using race-position - 1. */
|
||||||
|
std::vector<int> m_score_for_position;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/** Used for debugging to help detect if the same kart position
|
/** Used for debugging to help detect if the same kart position
|
||||||
* is used more than once. */
|
* is used more than once. */
|
||||||
@ -70,6 +74,8 @@ public:
|
|||||||
unsigned int position);
|
unsigned int position);
|
||||||
void endSetKartPositions();
|
void endSetKartPositions();
|
||||||
AbstractKart* getKartAtPosition(unsigned int p) const;
|
AbstractKart* getKartAtPosition(unsigned int p) const;
|
||||||
|
virtual int getScoreForPosition(int p);
|
||||||
|
|
||||||
|
|
||||||
virtual unsigned int getNumberOfRescuePositions() const OVERRIDE;
|
virtual unsigned int getNumberOfRescuePositions() const OVERRIDE;
|
||||||
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE;
|
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE;
|
||||||
|
@ -446,8 +446,12 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
{
|
{
|
||||||
btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1);
|
btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1);
|
||||||
btVector3 terrain_up(0,1,0);
|
btVector3 terrain_up(0,1,0);
|
||||||
|
// Length of axis depends on the angle - i.e. the further awat
|
||||||
|
// the kart is from being upright, the larger the applied impulse
|
||||||
|
// will be, resulting in fast changes when the kart is on its
|
||||||
|
// side, but not overcompensating (and therefore shaking) when
|
||||||
|
// the kart is not much away from being upright.
|
||||||
btVector3 axis = kart_up.cross(terrain_up);
|
btVector3 axis = kart_up.cross(terrain_up);
|
||||||
axis.normalize();
|
|
||||||
|
|
||||||
// To avoid the kart going backwards/forwards (or rolling sideways),
|
// To avoid the kart going backwards/forwards (or rolling sideways),
|
||||||
// set the pitch/roll to 0 before applying the 'straightening' impulse.
|
// set the pitch/roll to 0 before applying the 'straightening' impulse.
|
||||||
|
@ -39,8 +39,6 @@ GrandPrixManager::GrandPrixManager()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GrandPrixManager::~GrandPrixManager()
|
GrandPrixManager::~GrandPrixManager()
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
|
||||||
delete m_gp_data[i];
|
|
||||||
} // ~GrandPrixManager
|
} // ~GrandPrixManager
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -84,9 +82,10 @@ void GrandPrixManager::loadDir(const std::string& dir, enum GrandPrixData::GPGro
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPGroupType group)
|
void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPGroupType group)
|
||||||
{
|
{
|
||||||
|
GrandPrixData* gp = NULL;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GrandPrixData* gp = new GrandPrixData(filename, group);
|
gp = new GrandPrixData(filename, group);
|
||||||
m_gp_data.push_back(gp);
|
m_gp_data.push_back(gp);
|
||||||
Log::debug("GrandPrixManager",
|
Log::debug("GrandPrixManager",
|
||||||
"Grand Prix '%s' loaded from %s",
|
"Grand Prix '%s' loaded from %s",
|
||||||
@ -94,6 +93,8 @@ void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPG
|
|||||||
}
|
}
|
||||||
catch (std::runtime_error& e)
|
catch (std::runtime_error& e)
|
||||||
{
|
{
|
||||||
|
if (gp != NULL)
|
||||||
|
delete gp;
|
||||||
Log::error("GrandPrixManager",
|
Log::error("GrandPrixManager",
|
||||||
"Ignoring Grand Prix %s (%s)\n", filename.c_str(), e.what());
|
"Ignoring Grand Prix %s (%s)\n", filename.c_str(), e.what());
|
||||||
}
|
}
|
||||||
@ -102,9 +103,7 @@ void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPG
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GrandPrixManager::reload()
|
void GrandPrixManager::reload()
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
m_gp_data.clearAndDeleteAll();
|
||||||
delete m_gp_data[i];
|
|
||||||
m_gp_data.clear();
|
|
||||||
|
|
||||||
loadFiles();
|
loadFiles();
|
||||||
} // reload
|
} // reload
|
||||||
@ -124,7 +123,7 @@ std::string GrandPrixManager::generateId()
|
|||||||
unique = true;
|
unique = true;
|
||||||
for (unsigned int i = 0; i < m_gp_data.size(); i++)
|
for (unsigned int i = 0; i < m_gp_data.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_gp_data[i]->getId() == s.str())
|
if (m_gp_data[i].getId() == s.str())
|
||||||
{
|
{
|
||||||
unique = false;
|
unique = false;
|
||||||
break;
|
break;
|
||||||
@ -139,25 +138,31 @@ std::string GrandPrixManager::generateId()
|
|||||||
bool GrandPrixManager::existsName(const irr::core::stringw& name) const
|
bool GrandPrixManager::existsName(const irr::core::stringw& name) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < m_gp_data.size(); i++)
|
for (unsigned int i = 0; i < m_gp_data.size(); i++)
|
||||||
if (m_gp_data[i]->getName() == name)
|
if (m_gp_data[i].getName() == name)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} // existsName
|
} // existsName
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
|
const GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
|
||||||
{
|
{
|
||||||
return editGrandPrix(s);
|
for (unsigned int i = 0; i<m_gp_data.size(); i++)
|
||||||
|
{
|
||||||
|
if (m_gp_data[i].getId() == s)
|
||||||
|
return m_gp_data.get(i);
|
||||||
|
} // for i in m_gp_data
|
||||||
|
|
||||||
|
return NULL;
|
||||||
} // getGrandPrix
|
} // getGrandPrix
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s) const
|
GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s)
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
||||||
{
|
{
|
||||||
if(m_gp_data[i]->getId() == s)
|
if (m_gp_data[i].getId() == s)
|
||||||
return m_gp_data[i];
|
return m_gp_data.get(i);
|
||||||
} // for i in m_gp_data
|
} // for i in m_gp_data
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -166,13 +171,12 @@ GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s) const
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GrandPrixManager::checkConsistency()
|
void GrandPrixManager::checkConsistency()
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
for (int i = (int)m_gp_data.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if(!m_gp_data[i]->checkConsistency())
|
if (!m_gp_data[i].checkConsistency())
|
||||||
{
|
{
|
||||||
// delete this GP, since a track is missing
|
// delete this GP, since a track is missing
|
||||||
delete *(m_gp_data.erase(m_gp_data.begin()+i));
|
m_gp_data.erase(i);
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // checkConsistency
|
} // checkConsistency
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "utils/ptr_vector.hpp"
|
||||||
|
|
||||||
#include "irrlicht.h"
|
#include "irrlicht.h"
|
||||||
class GrandPrixData;
|
class GrandPrixData;
|
||||||
@ -35,7 +36,7 @@ class GrandPrixManager
|
|||||||
private:
|
private:
|
||||||
static const char* SUFFIX;
|
static const char* SUFFIX;
|
||||||
|
|
||||||
std::vector<GrandPrixData*> m_gp_data;
|
PtrVector<GrandPrixData> m_gp_data;
|
||||||
|
|
||||||
/** Load all the grands prix from the 3 directories known */
|
/** Load all the grands prix from the 3 directories known */
|
||||||
void loadFiles();
|
void loadFiles();
|
||||||
@ -51,20 +52,23 @@ public:
|
|||||||
GrandPrixManager();
|
GrandPrixManager();
|
||||||
~GrandPrixManager();
|
~GrandPrixManager();
|
||||||
void reload();
|
void reload();
|
||||||
GrandPrixData* getGrandPrix(const std::string& s) const;
|
|
||||||
bool existsName(const irr::core::stringw& name) const;
|
bool existsName(const irr::core::stringw& name) const;
|
||||||
void checkConsistency();
|
void checkConsistency();
|
||||||
|
|
||||||
// Methods for the gp editor
|
// Methods for the gp editor
|
||||||
GrandPrixData* editGrandPrix(const std::string& s) const;
|
GrandPrixData* editGrandPrix(const std::string& s);
|
||||||
GrandPrixData* createNewGP(const irr::core::stringw& newName);
|
GrandPrixData* createNewGP(const irr::core::stringw& newName);
|
||||||
GrandPrixData* copy(const std::string& id,
|
GrandPrixData* copy(const std::string& id,
|
||||||
const irr::core::stringw& newName);
|
const irr::core::stringw& newName);
|
||||||
void remove(const std::string& id);
|
void remove(const std::string& id);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
/** Returns a pointer to the data for the specified GP.
|
||||||
|
* \param i Index of the GP. */
|
||||||
|
const GrandPrixData* getGrandPrix(const std::string& s) const;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
/** Returns a pointer to the data for the specified GP.
|
/** Returns a pointer to the data for the specified GP.
|
||||||
* \param i Index of the GP. */
|
* \param i Index of the GP. */
|
||||||
GrandPrixData* getGrandPrix(const int i) const { return m_gp_data[i]; }
|
const GrandPrixData* getGrandPrix(const int i) const { return m_gp_data.get(i); }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the number of GPs. */
|
/** Returns the number of GPs. */
|
||||||
unsigned int getNumberOfGrandPrix() const { return (int)m_gp_data.size(); }
|
unsigned int getNumberOfGrandPrix() const { return (int)m_gp_data.size(); }
|
||||||
|
@ -182,6 +182,8 @@ void History::Save()
|
|||||||
fprintf(fd, "numkarts: %d\n", num_karts);
|
fprintf(fd, "numkarts: %d\n", num_karts);
|
||||||
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
|
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
|
||||||
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
||||||
|
fprintf(fd, "reverse: %c\n", race_manager->getReverseTrack() ? 'y' : 'n');
|
||||||
|
|
||||||
fprintf(fd, "track: %s\n", world->getTrack()->getIdent().c_str());
|
fprintf(fd, "track: %s\n", world->getTrack()->getIdent().c_str());
|
||||||
|
|
||||||
assert(num_karts > 0);
|
assert(num_karts > 0);
|
||||||
@ -269,7 +271,17 @@ void History::Load()
|
|||||||
Log::fatal("History", "No difficulty found in history file.");
|
Log::fatal("History", "No difficulty found in history file.");
|
||||||
race_manager->setDifficulty((RaceManager::Difficulty)n);
|
race_manager->setDifficulty((RaceManager::Difficulty)n);
|
||||||
|
|
||||||
|
|
||||||
|
// Optional (not supported in older history files): include reverse
|
||||||
fgets(s, 1023, fd);
|
fgets(s, 1023, fd);
|
||||||
|
char r;
|
||||||
|
if (!sscanf(s, "reverse: %c", &r) != 1)
|
||||||
|
{
|
||||||
|
fgets(s, 1023, fd);
|
||||||
|
race_manager->setReverseTrack(r == 'y');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(sscanf(s, "track: %1023s",s1)!=1)
|
if(sscanf(s, "track: %1023s",s1)!=1)
|
||||||
Log::warn("History", "Track not found in history file.");
|
Log::warn("History", "Track not found in history file.");
|
||||||
race_manager->setTrack(s1);
|
race_manager->setTrack(s1);
|
||||||
|
@ -416,7 +416,6 @@ void RaceManager::startNextRace()
|
|||||||
// Uncomment to debug audio leaks
|
// Uncomment to debug audio leaks
|
||||||
// sfx_manager->dump();
|
// sfx_manager->dump();
|
||||||
|
|
||||||
stk_config->getAllScores(&m_score_for_position, m_num_karts);
|
|
||||||
IrrlichtDevice* device = irr_driver->getDevice();
|
IrrlichtDevice* device = irr_driver->getDevice();
|
||||||
GUIEngine::renderLoading();
|
GUIEngine::renderLoading();
|
||||||
device->getVideoDriver()->endScene();
|
device->getVideoDriver()->endScene();
|
||||||
@ -547,7 +546,7 @@ void RaceManager::saveGP()
|
|||||||
m_saved_gp->setKarts(m_kart_status);
|
m_saved_gp->setKarts(m_kart_status);
|
||||||
m_saved_gp->setNextTrack(m_track_number);
|
m_saved_gp->setNextTrack(m_track_number);
|
||||||
}
|
}
|
||||||
else
|
else if(!m_grand_prix.isRandomGP())
|
||||||
{
|
{
|
||||||
m_saved_gp = new SavedGrandPrix(
|
m_saved_gp = new SavedGrandPrix(
|
||||||
StateManager::get()->getActivePlayerProfile(0)->getUniqueID(),
|
StateManager::get()->getActivePlayerProfile(0)->getUniqueID(),
|
||||||
@ -557,12 +556,30 @@ void RaceManager::saveGP()
|
|||||||
m_track_number,
|
m_track_number,
|
||||||
m_grand_prix.getReverseType(),
|
m_grand_prix.getReverseType(),
|
||||||
m_kart_status);
|
m_kart_status);
|
||||||
|
|
||||||
|
// If a new GP is saved, delete any other saved data for this
|
||||||
|
// GP at the same difficulty (even if #karts is different, otherwise
|
||||||
|
// the user has to remember the number of AI karts, with no indication
|
||||||
|
// on which ones are saved).
|
||||||
|
for (unsigned int i = 0;
|
||||||
|
i < UserConfigParams::m_saved_grand_prix_list.size();)
|
||||||
|
{
|
||||||
|
// Delete other save files (and random GP, which should never
|
||||||
|
// have been saved in the first place)
|
||||||
|
const SavedGrandPrix &sgp = UserConfigParams::m_saved_grand_prix_list[i];
|
||||||
|
if (sgp.getGPID() == "random" ||
|
||||||
|
(sgp.getGPID() == m_saved_gp->getGPID() &&
|
||||||
|
sgp.getDifficulty() == m_saved_gp->getDifficulty()) )
|
||||||
|
{
|
||||||
|
UserConfigParams::m_saved_grand_prix_list.erase(i);
|
||||||
|
}
|
||||||
|
else i++;
|
||||||
|
}
|
||||||
UserConfigParams::m_saved_grand_prix_list.push_back(m_saved_gp);
|
UserConfigParams::m_saved_grand_prix_list.push_back(m_saved_gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
user_config->saveConfig();
|
user_config->saveConfig();
|
||||||
}
|
} // saveGP
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -760,7 +777,17 @@ void RaceManager::kartFinishedRace(const AbstractKart *kart, float time)
|
|||||||
assert(pos-1 < (int)m_kart_status.size());
|
assert(pos-1 < (int)m_kart_status.size());
|
||||||
|
|
||||||
m_kart_status[id].m_last_score = m_kart_status[id].m_score;
|
m_kart_status[id].m_last_score = m_kart_status[id].m_score;
|
||||||
m_kart_status[id].m_score += m_score_for_position[pos-1];
|
|
||||||
|
// In follow the leader mode, the winner is actually the kart with
|
||||||
|
// position 2, so adjust the points (#points for leader do not matter)
|
||||||
|
WorldWithRank *wwr = dynamic_cast<WorldWithRank*>(World::getWorld());
|
||||||
|
if (wwr)
|
||||||
|
m_kart_status[id].m_score += wwr->getScoreForPosition(pos);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::error("RaceManager", "World with scores that is not a WorldWithRank??");
|
||||||
|
}
|
||||||
|
|
||||||
m_kart_status[id].m_overall_time += time;
|
m_kart_status[id].m_overall_time += time;
|
||||||
m_kart_status[id].m_last_time = time;
|
m_kart_status[id].m_last_time = time;
|
||||||
m_num_finished_karts ++;
|
m_num_finished_karts ++;
|
||||||
|
@ -313,10 +313,6 @@ private:
|
|||||||
/** Whether a track should be reversed */
|
/** Whether a track should be reversed */
|
||||||
std::vector<bool> m_reverse_track;
|
std::vector<bool> m_reverse_track;
|
||||||
|
|
||||||
/** The points given to a kart on a given position (index is
|
|
||||||
* 0 based, so using race-position - 1. */
|
|
||||||
std::vector<int> m_score_for_position;
|
|
||||||
|
|
||||||
/** The list of default AI karts to use. This is from the command line. */
|
/** The list of default AI karts to use. This is from the command line. */
|
||||||
std::vector<std::string> m_default_ai_list;
|
std::vector<std::string> m_default_ai_list;
|
||||||
|
|
||||||
@ -592,8 +588,6 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
float getTimeTarget() const { return m_time_target; }
|
float getTimeTarget() const { return m_time_target; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
int getPositionScore(int p) const { return m_score_for_position[p-1]; }
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
int getTrackNumber() const { return m_track_number; }
|
int getTrackNumber() const { return m_track_number; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the list of AI karts to use. Used for networking, and for
|
/** Returns the list of AI karts to use. Used for networking, and for
|
||||||
|
@ -331,12 +331,15 @@ void AddonsLoading::stopDownload()
|
|||||||
// (and not uninstalling an installed one):
|
// (and not uninstalling an installed one):
|
||||||
if(m_download_request)
|
if(m_download_request)
|
||||||
{
|
{
|
||||||
// In case of a cancel we can't free the memory, since
|
// In case of a cancel we can't free the memory, since the
|
||||||
// network_http will potentially update the request. So in
|
// request manager thread is potentially working on this request. So
|
||||||
// order to avoid a memory leak, we let network_http free
|
// in order to avoid a memory leak, we let the request manager
|
||||||
// the request.
|
// free the data. This is thread safe since freeing the data is done
|
||||||
//m_download_request->setManageMemory(true);
|
// when the request manager handles the result queue - and this is
|
||||||
|
// done by the main thread (i.e. this thread).
|
||||||
|
m_download_request->setManageMemory(true);
|
||||||
m_download_request->cancel();
|
m_download_request->cancel();
|
||||||
|
m_download_request = NULL;
|
||||||
};
|
};
|
||||||
} // startDownload
|
} // startDownload
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ void OptionsScreenAudio::init()
|
|||||||
{
|
{
|
||||||
Screen::init();
|
Screen::init();
|
||||||
RibbonWidget* ribbon = this->getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* ribbon = this->getWidget<RibbonWidget>("options_choice");
|
||||||
if (ribbon != NULL) ribbon->select( "tab_audio", PLAYER_ID_GAME_MASTER );
|
assert(ribbon != NULL);
|
||||||
|
ribbon->select( "tab_audio", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
||||||
ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
||||||
|
@ -133,7 +133,8 @@ void OptionsScreenInput::init()
|
|||||||
{
|
{
|
||||||
Screen::init();
|
Screen::init();
|
||||||
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
|
||||||
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
assert(tabBar != NULL);
|
||||||
|
tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
||||||
tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
||||||
|
@ -79,8 +79,8 @@ void OptionsScreenInput2::init()
|
|||||||
{
|
{
|
||||||
Screen::init();
|
Screen::init();
|
||||||
RibbonWidget* tabBar = getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* tabBar = getWidget<RibbonWidget>("options_choice");
|
||||||
if (tabBar != NULL) tabBar->select( "tab_controls",
|
assert(tabBar != NULL);
|
||||||
PLAYER_ID_GAME_MASTER );
|
tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
||||||
tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
||||||
@ -89,7 +89,7 @@ void OptionsScreenInput2::init()
|
|||||||
|
|
||||||
|
|
||||||
ButtonWidget* delete_button = getWidget<ButtonWidget>("delete");
|
ButtonWidget* delete_button = getWidget<ButtonWidget>("delete");
|
||||||
if (m_config->isKeyboard())
|
if (!m_config->isKeyboard())
|
||||||
{
|
{
|
||||||
core::stringw label = (m_config->isEnabled()
|
core::stringw label = (m_config->isEnabled()
|
||||||
? //I18N: button to disable a gamepad configuration
|
? //I18N: button to disable a gamepad configuration
|
||||||
|
@ -112,7 +112,8 @@ void OptionsScreenUI::init()
|
|||||||
{
|
{
|
||||||
Screen::init();
|
Screen::init();
|
||||||
RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
|
||||||
if (ribbon != NULL) ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER );
|
assert(ribbon != NULL);
|
||||||
|
ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
||||||
ribbon->getRibbonChildren()[1].setTooltip( _("Audio") );
|
ribbon->getRibbonChildren()[1].setTooltip( _("Audio") );
|
||||||
|
@ -159,7 +159,8 @@ void OptionsScreenVideo::init()
|
|||||||
{
|
{
|
||||||
Screen::init();
|
Screen::init();
|
||||||
RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
|
||||||
if (ribbon != NULL) ribbon->select( "tab_video", PLAYER_ID_GAME_MASTER );
|
assert(ribbon != NULL);
|
||||||
|
ribbon->select( "tab_video", PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
ribbon->getRibbonChildren()[1].setTooltip( _("Audio") );
|
ribbon->getRibbonChildren()[1].setTooltip( _("Audio") );
|
||||||
ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
||||||
|
@ -452,7 +452,6 @@ void RaceResultGUI::determineTableLayout()
|
|||||||
m_width_kart_name = 0;
|
m_width_kart_name = 0;
|
||||||
float max_finish_time = 0;
|
float max_finish_time = 0;
|
||||||
|
|
||||||
|
|
||||||
for(unsigned int position=first_position;
|
for(unsigned int position=first_position;
|
||||||
position<=race_manager->getNumberOfKarts(); position++)
|
position<=race_manager->getNumberOfKarts(); position++)
|
||||||
{
|
{
|
||||||
@ -469,7 +468,9 @@ void RaceResultGUI::determineTableLayout()
|
|||||||
kart->getKartProperties()->getIconMaterial()->getTexture();
|
kart->getKartProperties()->getIconMaterial()->getTexture();
|
||||||
ri->m_kart_icon = icon;
|
ri->m_kart_icon = icon;
|
||||||
|
|
||||||
if (kart->isEliminated())
|
// FTL karts will get a time assigned, they are not shown as eliminated
|
||||||
|
if (kart->isEliminated() &&
|
||||||
|
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||||
{
|
{
|
||||||
ri->m_finish_time_string = core::stringw(_("Eliminated"));
|
ri->m_finish_time_string = core::stringw(_("Eliminated"));
|
||||||
}
|
}
|
||||||
@ -764,18 +765,27 @@ void RaceResultGUI::renderGlobal(float dt)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RR_INCREASE_POINTS:
|
case RR_INCREASE_POINTS:
|
||||||
|
{
|
||||||
|
WorldWithRank *wwr = dynamic_cast<WorldWithRank*>(World::getWorld());
|
||||||
|
assert(wwr);
|
||||||
|
int most_points;
|
||||||
|
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||||
|
most_points = wwr->getScoreForPosition(2);
|
||||||
|
else
|
||||||
|
most_points = wwr->getScoreForPosition(1);
|
||||||
ri->m_current_displayed_points +=
|
ri->m_current_displayed_points +=
|
||||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
dt*most_points / m_time_for_points;
|
||||||
if(ri->m_current_displayed_points>ri->m_new_overall_points)
|
if (ri->m_current_displayed_points > ri->m_new_overall_points)
|
||||||
{
|
{
|
||||||
ri->m_current_displayed_points =
|
ri->m_current_displayed_points =
|
||||||
(float)ri->m_new_overall_points;
|
(float)ri->m_new_overall_points;
|
||||||
}
|
}
|
||||||
ri->m_new_points -=
|
ri->m_new_points -=
|
||||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
dt*most_points / m_time_for_points;
|
||||||
if(ri->m_new_points<0)
|
if (ri->m_new_points < 0)
|
||||||
ri->m_new_points = 0;
|
ri->m_new_points = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RR_RESORT_TABLE:
|
case RR_RESORT_TABLE:
|
||||||
x = ri->m_x_pos
|
x = ri->m_x_pos
|
||||||
- ri->m_radius*sin(m_timer/m_time_rotation*M_PI);
|
- ri->m_radius*sin(m_timer/m_time_rotation*M_PI);
|
||||||
@ -822,29 +832,35 @@ void RaceResultGUI::determineGPLayout()
|
|||||||
ri->m_player = ri->m_is_player_kart
|
ri->m_player = ri->m_is_player_kart
|
||||||
? kart->getController()->getPlayer() : NULL;
|
? kart->getController()->getPlayer() : NULL;
|
||||||
|
|
||||||
if (!kart->isEliminated())
|
// In FTL karts do have a time, which is shown even when the kart
|
||||||
|
// is eliminated
|
||||||
|
if (kart->isEliminated() &&
|
||||||
|
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
ri->m_finish_time_string = core::stringw(_("Eliminated"));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
float time = race_manager->getOverallTime(kart_id);
|
float time = race_manager->getOverallTime(kart_id);
|
||||||
ri->m_finish_time_string
|
ri->m_finish_time_string
|
||||||
= StringUtils::timeToString(time).c_str();
|
= StringUtils::timeToString(time).c_str();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ri->m_finish_time_string = core::stringw(_("Eliminated"));
|
|
||||||
}
|
|
||||||
ri->m_start_at = m_time_between_rows * rank;
|
ri->m_start_at = m_time_between_rows * rank;
|
||||||
ri->m_x_pos = (float)UserConfigParams::m_width;
|
ri->m_x_pos = (float)UserConfigParams::m_width;
|
||||||
ri->m_y_pos = (float)(m_top+rank*m_distance_between_rows);
|
ri->m_y_pos = (float)(m_top+rank*m_distance_between_rows);
|
||||||
int p = race_manager->getKartPrevScore(kart_id);
|
int p = race_manager->getKartPrevScore(kart_id);
|
||||||
ri->m_current_displayed_points = (float)p;
|
ri->m_current_displayed_points = (float)p;
|
||||||
if (kart->isEliminated())
|
if (kart->isEliminated() &&
|
||||||
|
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||||
{
|
{
|
||||||
ri->m_new_points = 0;
|
ri->m_new_points = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
WorldWithRank *wwr = dynamic_cast<WorldWithRank*>(World::getWorld());
|
||||||
|
assert(wwr);
|
||||||
ri->m_new_points =
|
ri->m_new_points =
|
||||||
(float)race_manager->getPositionScore(kart->getPosition());
|
(float)wwr->getScoreForPosition(kart->getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,15 +921,10 @@ void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y,
|
|||||||
current_x += m_width_kart_name + m_width_column_space;
|
current_x += m_width_kart_name + m_width_column_space;
|
||||||
|
|
||||||
|
|
||||||
// Draw the time except in FTL mode
|
core::recti dest_rect = core::recti(current_x, y, current_x + 100, y + 10);
|
||||||
// --------------------------------
|
m_font->draw(ri->m_finish_time_string, dest_rect, color, false, false,
|
||||||
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
NULL, true /* ignoreRTL */);
|
||||||
{
|
current_x += m_width_finish_time + m_width_column_space;
|
||||||
core::recti dest_rect = core::recti(current_x, y, current_x+100, y+10);
|
|
||||||
m_font->draw(ri->m_finish_time_string, dest_rect, color, false, false,
|
|
||||||
NULL, true /* ignoreRTL */);
|
|
||||||
current_x += m_width_finish_time + m_width_column_space;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only display points in GP mode and when the GP results are displayed.
|
// Only display points in GP mode and when the GP results are displayed.
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
@ -249,9 +249,6 @@ public:
|
|||||||
bool important=true,
|
bool important=true,
|
||||||
bool big_font=false) { }
|
bool big_font=false) { }
|
||||||
|
|
||||||
/** Should not be called anymore. */
|
|
||||||
virtual void clearAllMessages() {assert(false); }
|
|
||||||
|
|
||||||
void nextPhase();
|
void nextPhase();
|
||||||
|
|
||||||
/** Show no highscore */
|
/** Show no highscore */
|
||||||
|
@ -631,7 +631,8 @@ void BaseUserScreen::unloaded()
|
|||||||
void TabbedUserScreen::init()
|
void TabbedUserScreen::init()
|
||||||
{
|
{
|
||||||
RibbonWidget* tab_bar = getWidget<RibbonWidget>("options_choice");
|
RibbonWidget* tab_bar = getWidget<RibbonWidget>("options_choice");
|
||||||
if (tab_bar) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
|
assert(tab_bar != NULL);
|
||||||
|
tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
|
||||||
tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") );
|
||||||
tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") );
|
||||||
tab_bar->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
tab_bar->getRibbonChildren()[2].setTooltip( _("User Interface") );
|
||||||
|
@ -885,6 +885,18 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
|
|||||||
if (mb->getVertexType() == video::EVT_STANDARD)
|
if (mb->getVertexType() == video::EVT_STANDARD)
|
||||||
{
|
{
|
||||||
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
|
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
|
||||||
|
if (race_manager->getReverseTrack() &&
|
||||||
|
material->getMirrorAxisInReverse() != ' ')
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < mb->getVertexCount(); i++)
|
||||||
|
{
|
||||||
|
core::vector2df &tc = mb->getTCoords(i);
|
||||||
|
if (material->getMirrorAxisInReverse() == 'V')
|
||||||
|
tc.Y = 1 - tc.Y;
|
||||||
|
else
|
||||||
|
tc.X = 1 - tc.X;
|
||||||
|
}
|
||||||
|
} // reverse track and texture needs mirroring
|
||||||
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
|
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < mb->getIndexCount(); j += 3)
|
for (unsigned int j = 0; j < mb->getIndexCount(); j += 3)
|
||||||
@ -1736,7 +1748,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
|||||||
|
|
||||||
if (!m_is_arena && !m_is_soccer && !m_is_cutscene)
|
if (!m_is_arena && !m_is_soccer && !m_is_cutscene)
|
||||||
{
|
{
|
||||||
m_start_transforms.resize(race_manager->getNumberOfKarts());
|
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
// In a FTL race the non-leader karts are placed at the end of the
|
||||||
|
// field, so we need all start positions.
|
||||||
|
m_start_transforms.resize(stk_config->m_max_karts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_start_transforms.resize(race_manager->getNumberOfKarts());
|
||||||
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
||||||
karts_per_row,
|
karts_per_row,
|
||||||
forwards_distance,
|
forwards_distance,
|
||||||
|
@ -523,7 +523,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the start coordinates for a kart with a given index.
|
/** Returns the start coordinates for a kart with a given index.
|
||||||
* \param index Index of kart ranging from 0 to kart_num-1. */
|
* \param index Index of kart ranging from 0 to kart_num-1. */
|
||||||
btTransform getStartTransform (unsigned int index) const
|
const btTransform& getStartTransform (unsigned int index) const
|
||||||
{
|
{
|
||||||
if (index >= m_start_transforms.size())
|
if (index >= m_start_transforms.size())
|
||||||
Log::fatal("Track", "No start position for kart %i.", index);
|
Log::fatal("Track", "No start position for kart %i.", index);
|
||||||
|
@ -940,7 +940,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(
|
|||||||
|
|
||||||
std::string trigger_type;
|
std::string trigger_type;
|
||||||
xml_node.get("trigger-type", &trigger_type);
|
xml_node.get("trigger-type", &trigger_type);
|
||||||
if (trigger_type == "point")
|
if (trigger_type == "point" || trigger_type.empty())
|
||||||
{
|
{
|
||||||
m_type = TRIGGER_TYPE_POINT;
|
m_type = TRIGGER_TYPE_POINT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user