Merge branch 'master' into Fix_particles

This commit is contained in:
Elderme 2015-08-13 18:25:18 +02:00
commit 392a7c3203
24 changed files with 414 additions and 304 deletions

View File

@ -2081,11 +2081,13 @@ void CIrrDeviceLinux::pollJoysticks()
for (u32 j= 0; j< ActiveJoysticks.size(); ++j)
{
JoystickInfo & info = ActiveJoysticks[j];
bool event_received = false;
#ifdef __FreeBSD__
struct joystick js;
if (read(info.fd, &js, sizeof(js)) == sizeof(js))
{
event_received = true;
info.persistentData.JoystickEvent.ButtonStates = js.b1 | (js.b2 << 1); /* should be a two-bit field */
info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis */
info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis */
@ -2098,14 +2100,23 @@ void CIrrDeviceLinux::pollJoysticks()
{
case JS_EVENT_BUTTON:
if (event.value)
info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number);
{
event_received = true;
info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number);
}
else
info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number);
{
event_received = true;
info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number);
}
break;
case JS_EVENT_AXIS:
if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES)
{
event_received = true;
info.persistentData.JoystickEvent.Axis[event.number] = event.value;
}
break;
default:
@ -2116,6 +2127,13 @@ void CIrrDeviceLinux::pollJoysticks()
// Send an irrlicht joystick event once per ::run() even if no new data were received.
(void)postEventFromUser(info.persistentData);
#ifdef _IRR_COMPILE_WITH_X11_
if (event_received)
{
XResetScreenSaver(display);
}
#endif
}
#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
}

View File

@ -978,7 +978,8 @@ SFXBase* SFXManager::quickSound(const std::string &sound_type)
else
{
SFXBase *base_sound = sound->second;
base_sound->play();
if (base_sound->getStatus() != SFXBase::SFX_PLAYING)
base_sound->play();
return base_sound;
}

View File

@ -1880,29 +1880,6 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
push[1] = 0.1f;
m_body->applyCentralImpulse( -4000.0f*push );
m_bounce_back_time = 2.0f;
core::stringw msg = _("You need more points\n"
"to enter this challenge!\n"
"Check the minimap for\n"
"available challenges.");
std::vector<core::stringw> parts =
StringUtils::split(msg, '\n', false);
// For now, until we have scripting, special-case
// the overworld... (TODO)
if (dynamic_cast<OverWorld*>(World::getWorld()) != NULL)
{
SFXManager::get()->quickSound("forcefield");
World::getWorld()->getRaceGUI()->clearAllMessages();
for (unsigned int n = 0; n < parts.size(); n++)
{
World::getWorld()->getRaceGUI()
->addMessage(parts[n], NULL, 4.0f,
video::SColor(255, 255,255,255),
true, true);
} // for n<parts.size()
} // if world exist
} // if m_bounce_back_time <= 0.2f
} // if (m->getCollisionReaction() == Material::PUSH_BACK)
} // if(m && m->getCollisionReaction() != Material::NORMAL &&

View File

@ -224,10 +224,6 @@ void OverWorld::onFirePressed(Controller* who)
for (unsigned int n=0; n<challenges.size(); n++)
{
if ( challenges[n].isForceFieldSet() &&
challenges[n].getForceField().m_is_locked )
continue;
if ( (kart_xyz - Vec3(challenges[n].m_position)).length2_2d()
< CHALLENGE_DISTANCE_SQUARED)
{
@ -238,9 +234,22 @@ void OverWorld::onFirePressed(Controller* who)
}
else
{
race_manager->setKartLastPositionOnOverworld(kart_xyz);
new SelectChallengeDialog(0.8f, 0.8f,
challenges[n].m_challenge_id);
const ChallengeData* challenge = unlock_manager->getChallengeData(challenges[n].m_challenge_id);
if (challenge == NULL)
{
Log::error("track", "Cannot find challenge named '%s'\n",
challenges[n].m_challenge_id.c_str());
continue;
}
const unsigned int val = challenge->getNumTrophies();
bool unlocked = (PlayerManager::getCurrentPlayer()->getPoints() >= val);
if (unlocked)
{
race_manager->setKartLastPositionOnOverworld(kart_xyz);
new SelectChallengeDialog(0.8f, 0.8f,
challenges[n].m_challenge_id);
}
}
} // end if
} // end for

View File

@ -26,3 +26,29 @@ TutorialWorld::TutorialWorld()
{
m_stop_music_when_dialog_open = false;
} // TutorialWorld
unsigned int TutorialWorld::getRescuePositionIndex(AbstractKart *kart)
{
const int start_spots_amount = getTrack()->getNumberOfStartPositions();
assert(start_spots_amount > 0);
float closest_distance = 999999.0f;
int closest_id_found = 0;
Vec3 kart_pos = kart->getFrontXYZ();
for (int n = 0; n<start_spots_amount; n++)
{
const btTransform &s = getStartTransform(n);
const Vec3 &v = s.getOrigin();
float distance = (v - kart_pos).length2_2d();
if (n == 0 || distance < closest_distance)
{
closest_id_found = n;
closest_distance = distance;
}
}
return closest_id_found;
}

View File

@ -35,12 +35,7 @@ public:
}
// ------------------------------------------------------------------------
/** Determines the rescue position index of the specified kart. */
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE
{
// Don't use LinearWorld's function, but WorldWithRank, since the
// latter is based on rescuing to start positions
return WorldWithRank::getRescuePositionIndex(kart);
}
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE;
// ------------------------------------------------------------------------
/** Returns the bullet transformation for the specified rescue index. */
virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE
@ -50,6 +45,8 @@ public:
return WorldWithRank::getRescueTransform(index);
}
}; // class TutorialWorld
#endif

View File

@ -211,8 +211,6 @@ void World::init()
m_weather = new Weather(m_track->getWeatherLightning(),
m_track->getWeatherSound());
}
m_script_engine->compileLoadedScripts();
} // init
//-----------------------------------------------------------------------------

View File

@ -129,7 +129,7 @@ PhysicalObject::PhysicalObject(bool is_dynamic,
m_object = object;
m_init_xyz = object->getAbsolutePosition();
m_init_xyz = object->getAbsoluteCenterPosition();
m_init_hpr = object->getRotation();
m_init_scale = object->getScale();
@ -252,8 +252,14 @@ void PhysicalObject::init()
Log::fatal("PhysicalObject", "Unknown node type");
}
max = max * Vec3(m_init_scale);
min = min * Vec3(m_init_scale);
Vec3 parent_scale(1.0f, 1.0f, 1.0f);
if (m_object->getParentLibrary() != NULL)
{
parent_scale = m_object->getParentLibrary()->getScale();
}
max = max * (Vec3(m_init_scale) * parent_scale);
min = min * (Vec3(m_init_scale) * parent_scale);
Vec3 extend = max-min;
// Adjust the mesth of the graphical object so that its center is where it
@ -461,8 +467,31 @@ void PhysicalObject::init()
// 2. Create the rigid object
// --------------------------
// m_init_pos is the point on the track - add the offset
m_init_pos.setOrigin(m_init_pos.getOrigin() +
btVector3(0,extend.getY()*0.5f, 0));
if (m_is_dynamic)
{
m_init_pos.setOrigin(m_init_pos.getOrigin() +
btVector3(0, extend.getY()*0.5f, 0));
}
// If this object has a parent, apply the parent's rotation
if (m_object->getParentLibrary() != NULL)
{
core::vector3df parent_rot_hpr = m_object->getParentLibrary()->getInitRotation();
core::matrix4 parent_rot_matrix;
parent_rot_matrix.setRotationDegrees(parent_rot_hpr);
btQuaternion child_rot_quat = m_init_pos.getRotation();
core::matrix4 child_rot_matrix;
Vec3 axis = child_rot_quat.getAxis();
child_rot_matrix.setRotationAxisRadians(child_rot_quat.getAngle(), axis.toIrrVector());
irr::core::quaternion tempQuat(parent_rot_matrix * child_rot_matrix);
btQuaternion q(tempQuat.X, tempQuat.Y, tempQuat.Z, tempQuat.W);
m_init_pos.setRotation(q);
}
m_motion_state = new btDefaultMotionState(m_init_pos);
btVector3 inertia(1,1,1);
if (m_body_type != MP_EXACT)

View File

@ -19,10 +19,14 @@
#include "script_track.hpp"
#include "animations/three_d_animation.hpp"
#include "input/device_manager.hpp"
#include "input/input_device.hpp"
#include "input/input_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "modes/world.hpp"
#include "config/player_manager.hpp"
#include "states_screens/dialogs/tutorial_message_dialog.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object.hpp"
@ -30,6 +34,8 @@
#include <angelscript.h>
#include <assert.h>
#include <ISceneManager.h>
#include <IBillboardTextSceneNode.h>
/** \cond DOXYGEN_IGNORE */
namespace Scripting
@ -58,6 +64,38 @@ namespace Scripting
return track->getChallengeList().size();
}
int getChallengeRequiredPoints(std::string* challenge_name)
{
::Track* track = World::getWorld()->getTrack();
const ChallengeData* challenge = unlock_manager->getChallengeData(*challenge_name);
if (challenge == NULL)
{
if (*challenge_name != "tutorial")
Log::error("track", "Cannot find challenge named '%s'\n",
challenge_name->c_str());
return false;
}
return challenge->getNumTrophies();
}
bool isChallengeUnlocked(std::string* challenge_name)
{
::Track* track = World::getWorld()->getTrack();
const ChallengeData* challenge = unlock_manager->getChallengeData(*challenge_name);
if (challenge == NULL)
{
if (*challenge_name != "tutorial")
Log::error("track", "Cannot find challenge named '%s'\n",
challenge_name->c_str());
return false;
}
const unsigned int val = challenge->getNumTrophies();
bool shown = (PlayerManager::getCurrentPlayer()->getPoints() >= val);
return shown;
}
/** @}*/
/** @}*/
@ -69,6 +107,8 @@ namespace Scripting
r = engine->RegisterGlobalFunction("int getCompletedChallengesCount()", asFUNCTION(getCompletedChallengesCount), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("int getChallengeCount()", asFUNCTION(getChallengeCount), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("bool isChallengeUnlocked(string &in)", asFUNCTION(isChallengeUnlocked), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("int getChallengeRequiredPoints(string &in)", asFUNCTION(getChallengeRequiredPoints), asCALL_CDECL); assert(r >= 0);
}
}

View File

@ -107,7 +107,7 @@ namespace Scripting
script.resize(len);
int c = fread(&script[0], len, 1, f);
fclose(f);
if (c == NULL)
if (c != 1)
{
Log::error("Scripting", "Failed to load script file.");
return "";

View File

@ -53,20 +53,40 @@ namespace Scripting
{
InputDevice* device = input_manager->getDeviceManager()->getLatestUsedDevice();
DeviceConfig* config = device->getConfiguration();
irr::core::stringw control;
PlayerAction ScriptAction = (PlayerAction)Enum_value;
control = config->getBindingAsString(ScriptAction);
std::string key = std::string(irr::core::stringc(control).c_str());
irr::core::stringw control = config->getBindingAsString(ScriptAction);
std::string key = StringUtils::wide_to_utf8(control.c_str());
return key;
}
/** Show the specified message in a popup */
void displayMessage(std::string* input)
void displayModalMessage(std::string* input)
{
irr::core::stringw out = StringUtils::utf8_to_wide(input->c_str());
new TutorialMessageDialog((out), true);
}
void clearOverlayMessages()
{
World::getWorld()->getRaceGUI()->clearAllMessages();
}
/** Display text in the center of the screen for a few seconds */
void displayOverlayMessage(std::string* input)
{
irr::core::stringw msg = StringUtils::utf8_to_wide(input->c_str());
std::vector<core::stringw> parts =
StringUtils::split(msg, '\n', false);
for (unsigned int n = 0; n < parts.size(); n++)
{
World::getWorld()->getRaceGUI()
->addMessage(parts[n], NULL, 4.0f,
video::SColor(255, 255,255,255),
true, true);
} // for n<parts.size()
}
/** Get translated version of string */
std::string translate(std::string* input)
{
@ -150,7 +170,9 @@ namespace Scripting
{
int r; // of type asERetCodes
engine->SetDefaultNamespace("GUI");
r = engine->RegisterGlobalFunction("void displayMessage(const string &in)", asFUNCTION(displayMessage), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void displayModalMessage(const string &in)", asFUNCTION(displayModalMessage), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void displayOverlayMessage(const string &in)", asFUNCTION(displayOverlayMessage), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void clearOverlayMessages()", asFUNCTION(clearOverlayMessages), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("string getKeyBinding(int input)", asFUNCTION(getKeyBinding), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("string translate(const string &in)", asFUNCTION(proxy_translate), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("string translate(const string &in, const string &in)", asFUNCTION(proxy_translateAndInsertValues1), asCALL_CDECL); assert(r >= 0);

View File

@ -19,6 +19,9 @@
#include "script_track.hpp"
#include "animations/three_d_animation.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/stk_text_billboard.hpp"
#include "guiengine/scalable_font.hpp"
#include "input/device_manager.hpp"
#include "input/input_device.hpp"
#include "input/input_manager.hpp"
@ -29,8 +32,10 @@
#include "tracks/track_object.hpp"
#include "tracks/track_object_manager.hpp"
#include <IBillboardTextSceneNode.h>
#include <angelscript.h>
#include <assert.h>
#include <ISceneManager.h>
/** \cond DOXYGEN_IGNORE */
namespace Scripting
@ -57,13 +62,13 @@ namespace Scripting
* Get a track object by ID.
* @return An object of type @ref Scripting_TrackObject
*/
TrackObject* getTrackObject(std::string* libraryInstance, std::string* objID)
::TrackObject* getTrackObject(std::string* libraryInstance, std::string* objID)
{
return World::getWorld()->getTrack()->getTrackObjectManager()->getTrackObject(*libraryInstance, *objID);
}
/** Creates a trigger at the specified location */
void createTrigger(std::string* triggerID, Vec3* creation_loc, float distance)
void createTrigger(std::string* triggerID, SimpleVec3* creation_loc, float distance)
{
float x = creation_loc->getX();
float y = creation_loc->getY();
@ -73,12 +78,51 @@ namespace Scripting
core::vector3df scale(1.0f, 1.0f, 1.0f);
TrackObjectPresentationActionTrigger* newtrigger =
new TrackObjectPresentationActionTrigger(posi, *triggerID, distance);
TrackObject* tobj = new TrackObject(posi, hpr, scale,
::TrackObject* tobj = new ::TrackObject(posi, hpr, scale,
"none", newtrigger, false /* isDynamic */, NULL /* physics settings */);
tobj->setID(*triggerID);
World::getWorld()->getTrack()->getTrackObjectManager()->insertObject(tobj);
}
void createTextBillboard(std::string* text, SimpleVec3* location)
{
core::stringw wtext = StringUtils::utf8_to_wide(text->c_str());
core::dimension2d<u32> textsize = GUIEngine::getHighresDigitFont()
->getDimension(wtext.c_str());
assert(GUIEngine::getHighresDigitFont() != NULL);
core::vector3df xyz(location->getX(), location->getY(), location->getZ());
if (CVS->isGLSL())
{
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
STKTextBillboard* tb = new STKTextBillboard(wtext.c_str(), font,
video::SColor(255, 255, 225, 0),
video::SColor(255, 255, 89, 0),
irr_driver->getSceneManager()->getRootSceneNode(),
irr_driver->getSceneManager(), -1, xyz,
core::vector3df(1.5f, 1.5f, 1.5f));
World::getWorld()->getTrack()->addNode(tb);
}
else
{
scene::ISceneManager* sm = irr_driver->getSceneManager();
scene::ISceneNode* sn =
sm->addBillboardTextSceneNode(GUIEngine::getHighresDigitFont(),
wtext.c_str(),
NULL,
core::dimension2df(textsize.Width / 35.0f,
textsize.Height / 35.0f),
xyz,
-1, // id
video::SColor(255, 255, 225, 0),
video::SColor(255, 255, 89, 0));
World::getWorld()->getTrack()->addNode(sn);
}
}
/** Exits the race to the main menu */
void exitRace()
{
@ -96,6 +140,21 @@ namespace Scripting
{
/** \endcond */
namespace TrackObject
{
SimpleVec3 getCenterPosition(::TrackObject* obj)
{
core::vector3df pos = obj->getAbsoluteCenterPosition();
return SimpleVec3(pos.X, pos.Y, pos.Z);
}
SimpleVec3 getOrigin(::TrackObject* obj)
{
core::vector3df pos = obj->getAbsolutePosition();
return SimpleVec3(pos.X, pos.Y, pos.Z);
}
}
// ----------- TrackObjectPresentationMesh methods -----------
// TODO: this method is WRONG, we should in most cases move not the presentation but the entire object
//void movePresentation(Vec3 *new_pos, void *memory)
@ -237,19 +296,22 @@ namespace Scripting
//r = engine->RegisterGlobalFunction("void disableTrigger(const string &in)", asFUNCTION(disableTrigger), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void createTrigger(const string &in, const Vec3 &in, float distance)",
asFUNCTION(createTrigger), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void createTextBillboard(const string &in, const Vec3 &in)",
asFUNCTION(createTextBillboard), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("TrackObject@ getTrackObject(const string &in, const string &in)", asFUNCTION(getTrackObject), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void exitRace()", asFUNCTION(exitRace), asCALL_CDECL); assert(r >= 0);
r = engine->RegisterGlobalFunction("void pauseRace()", asFUNCTION(pauseRace), asCALL_CDECL); assert(r >= 0);
// TrackObject
r = engine->RegisterObjectMethod("TrackObject", "void setEnabled(bool status)", asMETHOD(TrackObject, setEnabled), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "SoundEmitter@ getSoundEmitter()", asMETHOD(TrackObject, getSoundEmitter), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "PhysicalObject@ getPhysics()", asMETHOD(TrackObject, getPhysics), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Mesh@ getMesh()", asMETHOD(TrackObject, getMesh), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "ParticleEmitter@ getParticleEmitter()", asMETHOD(TrackObject, getParticleEmitter), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Animator@ getIPOAnimator()", asMETHOD(TrackObject, getIPOAnimator), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "void moveTo(const Vec3 &in, bool)", asMETHOD(TrackObject, moveTo), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "void setEnabled(bool status)", asMETHOD(::TrackObject, setEnabled), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "SoundEmitter@ getSoundEmitter()", asMETHOD(::TrackObject, getSoundEmitter), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "PhysicalObject@ getPhysics()", asMETHOD(::TrackObject, getPhysics), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Mesh@ getMesh()", asMETHOD(::TrackObject, getMesh), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "ParticleEmitter@ getParticleEmitter()", asMETHOD(::TrackObject, getParticleEmitter), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Animator@ getIPOAnimator()", asMETHOD(::TrackObject, getIPOAnimator), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "void moveTo(const Vec3 &in, bool)", asMETHOD(::TrackObject, moveTo), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Vec3 getCenterPosition()", asFUNCTION(TrackObject::getCenterPosition), asCALL_CDECL_OBJLAST); assert(r >= 0);
r = engine->RegisterObjectMethod("TrackObject", "Vec3 getOrigin()", asFUNCTION(TrackObject::getOrigin), asCALL_CDECL_OBJLAST); assert(r >= 0);
// PhysicalObject
r = engine->RegisterObjectMethod("PhysicalObject", "bool isFlattenKartObject()", asMETHOD(PhysicalObject, isFlattenKartObject), asCALL_THISCALL); assert(r >= 0);

View File

@ -16,10 +16,10 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/irr_driver.hpp"
#include "states_screens/cutscene_gui.hpp"
// -----------------------------------------------------------------------------
@ -40,21 +40,23 @@ CutsceneGUI::~CutsceneGUI()
void CutsceneGUI::renderGlobal(float dt)
{
core::dimension2d<u32> screen_size = irr_driver->getActualScreenSize();
if (m_fade_level > 0.0f)
{
GL32_draw2DRectangle(
video::SColor((int)(m_fade_level*255), 0,0,0),
core::rect<s32>(0, 0,
UserConfigParams::m_width,
UserConfigParams::m_height));
screen_size.Width,
screen_size.Height));
}
if (m_subtitle.size() > 0)
{
core::rect<s32> r(0, UserConfigParams::m_height - GUIEngine::getFontHeight()*2,
UserConfigParams::m_width, UserConfigParams::m_height);
core::rect<s32> r(0, screen_size.Height - GUIEngine::getFontHeight()*2,
screen_size.Width, screen_size.Height);
if (GUIEngine::getFont()->getDimension(m_subtitle.c_str()).Width > (unsigned int)UserConfigParams::m_width)
if (GUIEngine::getFont()->getDimension(m_subtitle.c_str()).Width > screen_size.Width)
{
GUIEngine::getSmallFont()->draw(m_subtitle, r,
video::SColor(255,255,255,255), true, true, NULL);

View File

@ -171,16 +171,19 @@ void EditGPScreen::init()
if (edit->getResult())
{
bool reverse = edit->getTrack()->reverseAvailable() ?
edit->getReverse() : false;
if (m_action == "add")
{
m_gp->addTrack(edit->getTrack(), edit->getLaps(), edit->getReverse(),
m_selected);
m_gp->addTrack(edit->getTrack(), edit->getLaps(), reverse,
m_selected);
setSelected(m_selected + 1);
}
else if (m_action == "edit")
{
m_gp->editTrack(m_selected, edit->getTrack(), edit->getLaps(),
edit->getReverse());
reverse);
}
setModified(true);
}

View File

@ -291,6 +291,7 @@ void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName)
{
m_selection->setName(newName);
m_selection->writeToFile();
setSelection(grand_prix_manager->getGrandPrix(m_selection->getId()));
}
else if (m_action == "new")
{

View File

@ -95,6 +95,13 @@ static GFXPreset GFX_PRESETS[] =
false /* depth of field */, false /* global illumination */, false /* degraded IBL */, 1 /* hd_textures */
},
{
true /* light */, 512 /* shadow */, true /* bloom */, true /* motionblur */,
true /* lightshaft */, true /* glow */, true /* mlaa */, true /* ssao */, true /* weather */,
true /* animatedScenery */, 2 /* animatedCharacters */, 16 /* anisotropy */,
true /* depth of field */, false /* global illumination */, false /* degraded IBL */, 1 /* hd_textures */
},
{
true /* light */, 1024 /* shadow */, true /* bloom */, true /* motionblur */,
true /* lightshaft */, true /* glow */, true /* mlaa */, true /* ssao */, true /* weather */,
@ -103,7 +110,7 @@ static GFXPreset GFX_PRESETS[] =
}
};
static const int GFX_LEVEL_AMOUNT = 5;
static const int GFX_LEVEL_AMOUNT = 6;
struct Resolution
{

View File

@ -399,9 +399,10 @@ void RaceGUIOverworld::drawGlobalMiniMap()
Vec3 draw_at;
track->mapPoint2MiniMap(challenges[n].m_position, &draw_at);
//const ChallengeData* c = unlock_manager->getChallenge(challenges[n].m_challenge_id);
// bool locked = (m_locked_challenges.find(c) != m_locked_challenges.end());
int state = (challenges[n].getForceField().m_is_locked ? LOCKED : OPEN);
const ChallengeData* challenge = unlock_manager->getChallengeData(challenges[n].m_challenge_id);
const unsigned int val = challenge->getNumTrophies();
bool unlocked = (PlayerManager::getCurrentPlayer()->getPoints() >= val);
int state = (unlocked ? OPEN : LOCKED);
const ChallengeStatus* c = PlayerManager::getCurrentPlayer()
->getChallengeStatus(challenges[n].m_challenge_id);
@ -441,8 +442,14 @@ void RaceGUIOverworld::drawGlobalMiniMap()
m_close_to_a_challenge = false;
for (unsigned int n=0; n<challenges.size(); n++)
{
if (challenges[n].m_challenge_id != "tutorial" &&
challenges[n].getForceField().m_is_locked) continue;
if (challenges[n].m_challenge_id != "tutorial")
{
const ChallengeData* challenge = unlock_manager->getChallengeData(challenges[n].m_challenge_id);
const unsigned int val = challenge->getNumTrophies();
bool unlocked = (PlayerManager::getCurrentPlayer()->getPoints() >= val);
if (!unlocked)
continue;
}
if ((kart_xyz - Vec3(challenges[n].m_position)).length2_2d() < CHALLENGE_DISTANCE_SQUARED &&
fabsf(kart_xyz[1] - challenges[n].m_position.Y) < CHALLENGE_HEIGHT)

View File

@ -71,6 +71,7 @@
#include <IMeshManipulator.h>
#include <IMeshSceneNode.h>
#include <ISceneManager.h>
#include <SMeshBuffer.h>
#include <iostream>
#include <stdexcept>
@ -293,6 +294,11 @@ void Track::cleanup()
irr_driver->removeNode(m_all_nodes[i]);
}
m_all_nodes.clear();
for (unsigned int i = 0; i < m_static_physics_only_nodes.size(); i++)
{
m_static_physics_only_nodes[i]->remove();
}
m_static_physics_only_nodes.clear();
m_all_emitters.clearAndDeleteAll();
@ -736,9 +742,32 @@ void Track::createPhysicsModel(unsigned int main_track_count)
for (unsigned int i = 0; i<m_static_physics_only_nodes.size(); i++)
{
convertTrackToBullet(m_static_physics_only_nodes[i]);
irr_driver->removeNode(m_static_physics_only_nodes[i]);
if (UserConfigParams::m_physics_debug &&
m_static_physics_only_nodes[i]->getType() == scene::ESNT_MESH)
{
const video::SColor color(255, 255, 105, 180);
scene::IMesh *mesh = ((scene::IMeshSceneNode*)m_static_physics_only_nodes[i])->getMesh();
scene::IMeshBuffer *mb = mesh->getMeshBuffer(0);
mb->getMaterial().BackfaceCulling = false;
video::S3DVertex * const verts = (video::S3DVertex *) mb->getVertices();
const u32 max = mb->getVertexCount();
for (i = 0; i < max; i++)
{
verts[i].Color = color;
}
// Color
mb->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(255, 255, 105, 180)));
irr_driver->grabAllTextures(mesh);
// Gloss
mb->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
}
else
irr_driver->removeNode(m_static_physics_only_nodes[i]);
}
m_static_physics_only_nodes.clear();
if (!UserConfigParams::m_physics_debug)
m_static_physics_only_nodes.clear();
for (unsigned int i = 0; i<m_object_physics_only_nodes.size(); i++)
{
@ -834,7 +863,7 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
// FIXME: take translation/rotation into account
if (mb->getVertexType() != video::EVT_STANDARD &&
mb->getVertexType() != video::EVT_2TCOORDS &&
@ -988,7 +1017,6 @@ bool Track::loadMainTrack(const XMLNode &root)
assert(m_gfx_effect_mesh==NULL);
m_challenges.clear();
m_force_fields.clear();
m_track_mesh = new TriangleMesh();
m_gfx_effect_mesh = new TriangleMesh();
@ -1117,7 +1145,6 @@ bool Track::loadMainTrack(const XMLNode &root)
continue;
}
core::vector3df xyz(0,0,0);
n->get("xyz", &xyz);
core::vector3df hpr(0,0,0);
@ -1125,117 +1152,6 @@ bool Track::loadMainTrack(const XMLNode &root)
core::vector3df scale(1.0f, 1.0f, 1.0f);
n->get("scale", &scale);
// some static meshes are conditional
std::string condition;
n->get("if", &condition);
// TODO: convert "if" and "ifnot" to scripting.
if (condition == "splatting")
{
if (!irr_driver->supportsSplatting()) continue;
}
else if (condition == "trophies")
{
// Associate force fields and challenges
// FIXME: this assumes that challenges will appear before force fields in scene.xml
// (which however seems to be the case atm)
int closest_challenge_id = -1;
float closest_distance = 99999.0f;
for (unsigned int c=0; c<m_challenges.size(); c++)
{
float dist = xyz.getDistanceFromSQ(m_challenges[c].m_position);
if (closest_challenge_id == -1 || dist < closest_distance)
{
closest_challenge_id = c;
closest_distance = dist;
}
}
assert(closest_challenge_id >= 0);
assert(closest_challenge_id < (int)m_challenges.size());
const std::string &s = m_challenges[closest_challenge_id].m_challenge_id;
const ChallengeData* challenge = unlock_manager->getChallengeData(s);
if (challenge == NULL)
{
if (s != "tutorial")
Log::error("track", "Cannot find challenge named '%s'\n",
m_challenges[closest_challenge_id].m_challenge_id.c_str());
continue;
}
const unsigned int val = challenge->getNumTrophies();
bool shown = (PlayerManager::getCurrentPlayer()->getPoints() < val);
m_force_fields.push_back(OverworldForceField(xyz, shown, val));
m_challenges[closest_challenge_id].setForceField(
m_force_fields[m_force_fields.size() - 1]);
core::stringw msg = StringUtils::toWString(val);
core::dimension2d<u32> textsize = GUIEngine::getHighresDigitFont()
->getDimension(msg.c_str());
assert(GUIEngine::getHighresDigitFont() != NULL);
if (CVS->isGLSL())
{
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
STKTextBillboard* tb = new STKTextBillboard(msg.c_str(), font,
video::SColor(255, 255, 225, 0),
video::SColor(255, 255, 89, 0),
irr_driver->getSceneManager()->getRootSceneNode(),
irr_driver->getSceneManager(), -1, xyz,
core::vector3df(1.5f, 1.5f, 1.5f));
m_all_nodes.push_back(tb);
}
else
{
scene::ISceneManager* sm = irr_driver->getSceneManager();
scene::ISceneNode* sn =
sm->addBillboardTextSceneNode(GUIEngine::getHighresDigitFont(),
msg.c_str(),
NULL,
core::dimension2df(textsize.Width / 35.0f,
textsize.Height / 35.0f),
xyz,
-1, // id
video::SColor(255, 255, 225, 0),
video::SColor(255, 255, 89, 0));
m_all_nodes.push_back(sn);
}
if (!shown) continue;
}
else if (condition.size() > 0)
{
unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction(true, "bool " + condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result == 0)
continue;
}
std::string neg_condition;
n->get("ifnot", &neg_condition);
if (neg_condition == "splatting")
{
if (irr_driver->supportsSplatting()) continue;
}
else if (neg_condition.size() > 0)
{
unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction(true, "bool " + neg_condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result != 0)
continue;
}
bool tangent = false;
n->get("tangents", &tangent);
@ -1253,49 +1169,6 @@ bool Track::loadMainTrack(const XMLNode &root)
bool lod_instance = false;
n->get("lod_instance", &lod_instance);
/*
if (tangent)
{
scene::IMesh* original_mesh = irr_driver->getMesh(full_path);
if (std::find(m_detached_cached_meshes.begin(),
m_detached_cached_meshes.end(),
original_mesh) == m_detached_cached_meshes.end())
{
m_detached_cached_meshes.push_back(original_mesh);
}
// create a node out of this mesh just for bullet; delete it after, normal maps are special
// and require tangent meshes
scene_node = irr_driver->addMesh(original_mesh, "original_mesh");
scene_node->setPosition(xyz);
scene_node->setRotation(hpr);
scene_node->setScale(scale);
convertTrackToBullet(scene_node);
scene_node->remove();
irr_driver->grabAllTextures(original_mesh);
scene::IMesh* mesh = MeshTools::createMeshWithTangents(original_mesh, &MeshTools::isNormalMap);
mesh->grab();
irr_driver->grabAllTextures(mesh);
m_all_cached_meshes.push_back(mesh);
scene_node = irr_driver->addMesh(mesh, "original_mesh_with_tangents");
scene_node->setPosition(xyz);
scene_node->setRotation(hpr);
scene_node->setScale(scale);
#ifdef DEBUG
std::string debug_name = model_name+" (tangent static track-object)";
scene_node->setName(debug_name.c_str());
#endif
handleAnimatedTextures(scene_node, *n);
m_all_nodes.push_back( scene_node );
}
else*/
if (lod_instance)
{
LODNode* node = lodLoader.instanciateAsLOD(n, NULL);
@ -1345,6 +1218,7 @@ bool Track::loadMainTrack(const XMLNode &root)
handleAnimatedTextures(scene_node, *n);
// for challenge orbs, a bit more work to do
// TODO: this is hardcoded for the overworld, convert to scripting
if (challenge.size() > 0)
{
const ChallengeData* c = NULL;
@ -1810,6 +1684,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
model_def_loader.cleanLibraryNodesAfterLoad();
World::getWorld()->getScriptEngine()->compileLoadedScripts();
// Init all track objects
m_track_object_manager->init();

View File

@ -69,30 +69,10 @@ namespace Scripting
const int HEIGHT_MAP_RESOLUTION = 256;
struct OverworldForceField
{
core::vector3df m_position;
bool m_is_locked;
int m_required_points;
OverworldForceField()
{
}
OverworldForceField(core::vector3df position, bool is_locked, int required_points)
{
m_position = position;
m_is_locked = is_locked;
m_required_points = required_points;
}
};
// TODO: eventually remove this and fully replace with scripting
struct OverworldChallenge
{
private:
OverworldForceField m_force_field;
bool m_force_field_set;
public:
core::vector3df m_position;
std::string m_challenge_id;
@ -100,27 +80,6 @@ public:
{
m_position = position;
m_challenge_id = challenge_id;
m_force_field_set = false;
}
void setForceField(OverworldForceField f)
{
m_force_field = f;
m_force_field_set = true;
}
OverworldForceField& getForceField()
{
assert(m_force_field_set);
return m_force_field;
}
bool isForceFieldSet() const { return m_force_field_set; }
const OverworldForceField& getForceField() const
{
assert(m_force_field_set);
return m_force_field;
}
};
@ -160,8 +119,6 @@ private:
/** Will only be used on overworld */
std::vector<OverworldChallenge> m_challenges;
std::vector<OverworldForceField> m_force_fields;
std::vector<Subtitle> m_subtitles;
/** Start transforms of karts (either the default, or the ones taken

View File

@ -131,23 +131,11 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
m_type = type;
m_initially_visible = true;
std::string condition;
xml_node.get("if", &condition);
if (condition == "false")
xml_node.get("if", &m_visibility_condition);
if (m_visibility_condition == "false")
{
m_initially_visible = false;
}
else if (condition.size() > 0)
{
unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::function<void(asIScriptContext*)> null_callback;
script_engine->runFunction(true, "bool " + condition + "()", null_callback,
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result == 0)
m_initially_visible = false;
}
if (!m_initially_visible)
setEnabled(false);
@ -295,6 +283,68 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
// ----------------------------------------------------------------------------
void TrackObject::onWorldReady()
{
if (m_visibility_condition == "false")
{
m_initially_visible = false;
}
else if (m_visibility_condition.size() > 0)
{
unsigned char result = -1;
Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine();
std::ostringstream fn_signature;
std::vector<std::string> arguments;
if (m_visibility_condition.find("(") != std::string::npos &&
m_visibility_condition.find(")") != std::string::npos)
{
// There are arguments to pass to the function
// TODO: For the moment we only support string arguments
// TODO: this parsing could be improved
unsigned first = m_visibility_condition.find("(");
unsigned last = m_visibility_condition.find_last_of(")");
std::string fn_name = m_visibility_condition.substr(0, first);
std::string str_arguments = m_visibility_condition.substr(first + 1, last - first - 1);
arguments = StringUtils::split(str_arguments, ',');
fn_signature << "bool " << fn_name << "(";
for (int i = 0; i < arguments.size(); i++)
{
if (i > 0)
fn_signature << ",";
fn_signature << "string";
}
fn_signature << ",Track::TrackObject@)";
}
else
{
fn_signature << "bool " << m_visibility_condition << "(Track::TrackObject@)";
}
TrackObject* self = this;
script_engine->runFunction(true, fn_signature.str(),
[&](asIScriptContext* ctx)
{
for (int i = 0; i < arguments.size(); i++)
{
ctx->SetArgObject(i, &arguments[i]);
}
ctx->SetArgObject(arguments.size(), self);
},
[&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); });
if (result == 0)
m_initially_visible = false;
}
if (!m_initially_visible)
setEnabled(false);
}
// ----------------------------------------------------------------------------
/** Destructor. Removes the node from the scene graph, and also
* drops the textures of the mesh. Sound buffers are also freed.
*/
@ -456,6 +506,17 @@ const core::vector3df& TrackObject::getPosition() const
return m_init_xyz;
} // getPosition
// ----------------------------------------------------------------------------
const core::vector3df TrackObject::getAbsoluteCenterPosition() const
{
if (m_presentation != NULL)
return m_presentation->getAbsoluteCenterPosition();
else
return m_init_xyz;
} // getAbsolutePosition
// ----------------------------------------------------------------------------
const core::vector3df TrackObject::getAbsolutePosition() const
@ -483,7 +544,7 @@ const core::vector3df& TrackObject::getScale() const
if (m_presentation != NULL)
return m_presentation->getScale();
else
return m_init_xyz;
return m_init_scale;
} // getScale
// ----------------------------------------------------------------------------

View File

@ -94,6 +94,8 @@ protected:
bool m_initially_visible;
std::string m_visibility_condition;
void init(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library);
@ -120,6 +122,7 @@ public:
virtual void reset();
const core::vector3df& getPosition() const;
const core::vector3df getAbsolutePosition() const;
const core::vector3df getAbsoluteCenterPosition() const;
const core::vector3df& getRotation() const;
const core::vector3df& getScale() const;
bool castRay(const btVector3 &from,
@ -135,7 +138,7 @@ public:
// ------------------------------------------------------------------------
/** To finish object constructions. Called after the track model
* is ready. */
virtual void init() {};
virtual void onWorldReady();
// ------------------------------------------------------------------------
/** Called when an explosion happens. As a default does nothing, will
* e.g. be overwritten by physical objects etc. */

View File

@ -66,11 +66,9 @@ void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent,
*/
void TrackObjectManager::init()
{
TrackObject* curr;
for_in (curr, m_all_objects)
for_var_in(TrackObject*, curr, m_all_objects)
{
curr->init();
curr->onWorldReady();
}
} // reset
// ----------------------------------------------------------------------------

View File

@ -88,6 +88,16 @@ const core::vector3df TrackObjectPresentationSceneNode::getAbsolutePosition() co
return m_node->getAbsolutePosition();
} // getAbsolutePosition
// ----------------------------------------------------------------------------
const core::vector3df TrackObjectPresentationSceneNode::getAbsoluteCenterPosition() const
{
if (m_node == NULL) return m_init_xyz;
m_node->updateAbsolutePosition();
core::aabbox3d<f32> bounds = m_node->getTransformedBoundingBox();
return bounds.getCenter();
}
// ----------------------------------------------------------------------------
const core::vector3df& TrackObjectPresentationSceneNode::getRotation() const
{

View File

@ -100,6 +100,11 @@ public:
return m_init_xyz;
} // getAbsolutePosition
// ------------------------------------------------------------------------
virtual const core::vector3df getAbsoluteCenterPosition() const
{
return m_init_xyz;
}
// ------------------------------------------------------------------------
/** Returns the initial rotation. */
virtual const core::vector3df& getRotation() const { return m_init_hpr; }
// ------------------------------------------------------------------------
@ -141,6 +146,7 @@ public:
// ------------------------------------------------------------------------
virtual const core::vector3df& getPosition() const OVERRIDE;
virtual const core::vector3df getAbsolutePosition() const OVERRIDE;
virtual const core::vector3df getAbsoluteCenterPosition() const OVERRIDE;
virtual const core::vector3df& getRotation() const OVERRIDE;
virtual const core::vector3df& getScale() const OVERRIDE;
virtual void move(const core::vector3df& xyz, const core::vector3df& hpr,