Continue work on scripting, fixing #2268. Use this as an opportunity to clean up a lot of old hardcoded overworld code, and replace it with cleaner scripting. Make sure to update SVN and the exporter (other commits in SVN coming soon)
This commit is contained in:
parent
43d5dbeb3e
commit
d488c043d1
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 &&
|
||||
|
@ -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
|
||||
|
@ -211,8 +211,6 @@ void World::init()
|
||||
m_weather = new Weather(m_track->getWeatherLightning(),
|
||||
m_track->getWeatherSound());
|
||||
}
|
||||
|
||||
m_script_engine->compileLoadedScripts();
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -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();
|
||||
|
||||
@ -461,8 +461,11 @@ 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));
|
||||
}
|
||||
m_motion_state = new btDefaultMotionState(m_init_pos);
|
||||
btVector3 inertia(1,1,1);
|
||||
if (m_body_type != MP_EXACT)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,12 +61,33 @@ namespace Scripting
|
||||
}
|
||||
|
||||
/** 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 +171,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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -988,7 +988,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 +1116,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 +1123,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 +1140,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 +1189,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 +1655,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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user