diff --git a/src/items/item.cpp b/src/items/item.cpp index b9115fdb4..bfa625f54 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -374,7 +374,7 @@ void Item::collected(const AbstractKart *kart, float t) if (m_listener != NULL) { - m_listener->onTriggerItemApproached(this); + m_listener->onTriggerItemApproached(); } if (dynamic_cast(World::getWorld()) != NULL) diff --git a/src/items/item.hpp b/src/items/item.hpp index 583f8322e..294a1ddd9 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -51,7 +51,7 @@ class TriggerItemListener { public: virtual ~TriggerItemListener() {} - virtual void onTriggerItemApproached(Item* who) = 0; + virtual void onTriggerItemApproached() = 0; }; /** diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 10e21d5e8..8591c5be6 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -172,7 +172,7 @@ void Physics::update(float dt) Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); int kartid1 = p->getUserPointer(0)->getPointerKart()->getWorldKartId(); int kartid2 = p->getUserPointer(1)->getPointerKart()->getWorldKartId(); - script_engine->runFunction("void onKartKartCollision(int, int)", + script_engine->runFunction(false, "void onKartKartCollision(int, int)", [=](asIScriptContext* ctx) { ctx->SetArgDWord(0, kartid1); ctx->SetArgDWord(1, kartid2); @@ -201,7 +201,7 @@ void Physics::update(float dt) if (scripting_function.size() > 0) { - script_engine->runFunction("void " + scripting_function + "(int, const string, const string)", + script_engine->runFunction(true, "void " + scripting_function + "(int, const string, const string)", [&](asIScriptContext* ctx) { ctx->SetArgDWord(0, kartId); ctx->SetArgObject(1, lib_id_ptr); @@ -274,7 +274,7 @@ void Physics::update(float dt) std::string scripting_function = obj->getOnItemCollisionFunction(); if (scripting_function.size() > 0) { - script_engine->runFunction("void " + scripting_function + "(int, int, const string)", + script_engine->runFunction(true, "void " + scripting_function + "(int, int, const string)", [&](asIScriptContext* ctx) { ctx->SetArgDWord(0, (int)flyable->getType()); ctx->SetArgDWord(1, flyable->getOwnerId()); diff --git a/src/scriptengine/script_engine.cpp b/src/scriptengine/script_engine.cpp index c9cdadf68..aae89ce57 100644 --- a/src/scriptengine/script_engine.cpp +++ b/src/scriptengine/script_engine.cpp @@ -175,20 +175,20 @@ namespace Scripting /** runs the specified script * \param string scriptName = name of script to run */ - void ScriptEngine::runFunction(std::string function_name) + void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name) { std::function callback; std::function get_return_value; - runFunction(function_name, callback, get_return_value); + runFunction(warn_if_not_found, function_name, callback, get_return_value); } //----------------------------------------------------------------------------- - void ScriptEngine::runFunction(std::string function_name, + void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name, std::function callback) { std::function get_return_value; - runFunction(function_name, callback, get_return_value); + runFunction(warn_if_not_found, function_name, callback, get_return_value); } //----------------------------------------------------------------------------- @@ -196,7 +196,7 @@ namespace Scripting /** runs the specified script * \param string scriptName = name of script to run */ - void ScriptEngine::runFunction(std::string function_name, + void ScriptEngine::runFunction(bool warn_if_not_found, std::string function_name, std::function callback, std::function get_return_value) { @@ -217,7 +217,10 @@ namespace Scripting if (func == NULL) { - Log::debug("Scripting", "Scripting function was not found : %s", function_name.c_str()); + if (warn_if_not_found) + Log::warn("Scripting", "Scripting function was not found : %s", function_name.c_str()); + else + Log::debug("Scripting", "Scripting function was not found : %s", function_name.c_str()); m_functions_cache[function_name] = NULL; // remember that this function is unavailable return; } @@ -233,6 +236,8 @@ namespace Scripting if (func == NULL) { + if (warn_if_not_found) + Log::warn("Scripting", "Scripting function was not found : %s", function_name.c_str()); return; // function unavailable } @@ -425,7 +430,7 @@ namespace Scripting curr.m_time -= dt; if (curr.m_time <= 0.0) { - runFunction("void " + curr.m_callback_name + "()"); + runFunction(true, "void " + curr.m_callback_name + "()"); m_pending_timeouts.erase(m_pending_timeouts.begin() + i); } } diff --git a/src/scriptengine/script_engine.hpp b/src/scriptengine/script_engine.hpp index ab0bd8fd1..4cc4f95fe 100644 --- a/src/scriptengine/script_engine.hpp +++ b/src/scriptengine/script_engine.hpp @@ -47,10 +47,10 @@ namespace Scripting ScriptEngine(); ~ScriptEngine(); - void runFunction(std::string function_name); - void runFunction(std::string function_name, + void runFunction(bool warn_if_not_found, std::string function_name); + void runFunction(bool warn_if_not_found, std::string function_name, std::function callback); - void runFunction(std::string function_name, + void runFunction(bool warn_if_not_found, std::string function_name, std::function callback, std::function get_return_value); void evalScript(std::string script_fragment); diff --git a/src/scriptengine/script_utils.cpp b/src/scriptengine/script_utils.cpp index dc925b0f6..06b726a92 100644 --- a/src/scriptengine/script_utils.cpp +++ b/src/scriptengine/script_utils.cpp @@ -101,11 +101,11 @@ namespace Scripting return StringUtils::wide_to_utf8(out.c_str()); } - /** Runs the script specified by the given string */ + /** Runs the script function specified by the given string */ void runScript(const std::string* str) { ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); - script_engine->runFunction(*str); + script_engine->runFunction(true, *str); } /** Generate a random integer value */ diff --git a/src/tracks/check_cylinder.cpp b/src/tracks/check_cylinder.cpp index dfe1111ff..669d271ae 100644 --- a/src/tracks/check_cylinder.cpp +++ b/src/tracks/check_cylinder.cpp @@ -22,14 +22,16 @@ #include #include "io/xml_node.hpp" +#include "items/item.hpp" #include "modes/world.hpp" #include "race/race_manager.hpp" -CheckCylinder::CheckCylinder(const XMLNode &node, unsigned int index) +CheckCylinder::CheckCylinder(const XMLNode &node, unsigned int index, TriggerItemListener* listener) : CheckStructure(node, index) { m_radius2 = 1; m_height = 0; + m_listener = listener; node.get("height", &m_height); node.get("radius", &m_radius2); m_radius2 *= m_radius2; @@ -56,12 +58,20 @@ bool CheckCylinder::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, unsigned int kart_id) { // TODO: this is the code for a sphere, rewrite for cylinder - float old_dist2 = (old_pos-m_center_point).length2(); - float new_dist2 = (new_pos-m_center_point).length2(); + Vec3 old_pos_xz(old_pos.x(), 0.0f, old_pos.z()); + Vec3 new_pos_xz(new_pos.x(), 0.0f, new_pos.z()); + Vec3 center_xz(m_center_point.x(), 0.0f, m_center_point.z()); + float old_dist2 = (old_pos_xz - center_xz).length2(); + float new_dist2 = (new_pos_xz - center_xz).length2(); m_is_inside[kart_id] = new_dist2=m_radius2 && new_dist2 < m_radius2) || + bool triggered = (old_dist2>=m_radius2 && new_dist2 < m_radius2) || (old_dist2< m_radius2 && new_dist2 >=m_radius2); + + if (triggered && m_listener != NULL) + m_listener->onTriggerItemApproached(); + + return triggered; } // isTriggered diff --git a/src/tracks/check_cylinder.hpp b/src/tracks/check_cylinder.hpp index 6dede2312..4af674561 100644 --- a/src/tracks/check_cylinder.hpp +++ b/src/tracks/check_cylinder.hpp @@ -23,6 +23,7 @@ class XMLNode; class CheckManager; +class TriggerItemListener; /** This class implements a check sphere that is used to change the ambient * light if a kart is inside this sphere. Besides a normal radius this @@ -45,8 +46,10 @@ private: /** Stores the distance of each kart from the center of this sphere. * This saves some computations. */ std::vector m_distance2; + TriggerItemListener* m_listener; public: - CheckCylinder(const XMLNode &node, unsigned int index); + CheckCylinder(const XMLNode &node, unsigned int index, + TriggerItemListener* listener); virtual ~CheckCylinder() {}; virtual bool isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, unsigned int kart_id); diff --git a/src/tracks/check_manager.cpp b/src/tracks/check_manager.cpp index cc6309d19..9d99710ec 100644 --- a/src/tracks/check_manager.cpp +++ b/src/tracks/check_manager.cpp @@ -59,8 +59,7 @@ void CheckManager::load(const XMLNode &node) } else if(type=="check-sphere") { - AmbientLightSphere *cs = new AmbientLightSphere(*check_node, - i); + CheckSphere *cs = new CheckSphere(*check_node, i); m_all_checks.push_back(cs); } // checksphere else diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 8f04de77b..18d7e79b7 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1200,7 +1200,7 @@ bool Track::loadMainTrack(const XMLNode &root) unsigned char result = -1; Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); std::function null_callback; - script_engine->runFunction("bool " + condition + "()", null_callback, + script_engine->runFunction(true, "bool " + condition + "()", null_callback, [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); if (result == 0) continue; @@ -1217,7 +1217,7 @@ bool Track::loadMainTrack(const XMLNode &root) unsigned char result = -1; Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); std::function null_callback; - script_engine->runFunction("bool " + neg_condition + "()", null_callback, + script_engine->runFunction(true, "bool " + neg_condition + "()", null_callback, [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); if (result != 0) continue; @@ -1488,7 +1488,7 @@ void Track::update(float dt) if (!m_startup_run) // first time running update = good point to run startup script { Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); - script_engine->runFunction("void onStart()"); + script_engine->runFunction(false, "void onStart()"); m_startup_run = true; } m_track_object_manager->update(dt); diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 78776e564..b407979b6 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -142,7 +142,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, unsigned char result = -1; Scripting::ScriptEngine* script_engine = World::getWorld()->getScriptEngine(); std::function null_callback; - script_engine->runFunction("bool " + condition + "()", null_callback, + script_engine->runFunction(true, "bool " + condition + "()", null_callback, [&](asIScriptContext* ctx) { result = ctx->GetReturnByte(); }); if (result == 0) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index a69909dbd..1c05723f6 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -652,7 +652,7 @@ void TrackObjectPresentationSound::update(float dt) } // update // ---------------------------------------------------------------------------- -void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) +void TrackObjectPresentationSound::onTriggerItemApproached() { if (m_sound != NULL && m_sound->getStatus() != SFXBase::SFX_PLAYING) { @@ -966,8 +966,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( } else if (m_type == TRIGGER_TYPE_CYLINDER) { - // TODO: create the right check structure - CheckManager::get()->add(new CheckCylinder(xml_node, 0 /* TODO what is this? */)); + CheckManager::get()->add(new CheckCylinder(xml_node, 0 /* TODO what is this? */, this)); } else { @@ -993,7 +992,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger( } // TrackObjectPresentationActionTrigger // ---------------------------------------------------------------------------- -void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) +void TrackObjectPresentationActionTrigger::onTriggerItemApproached() { if (!m_action_active) return; @@ -1004,6 +1003,6 @@ void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) Camera* camera = Camera::getActiveCamera(); if (camera != NULL && camera->getKart() != NULL) idKart = camera->getKart()->getWorldKartId(); - script_engine->runFunction("void " + m_action + "(int)", + script_engine->runFunction(true, "void " + m_action + "(int)", [=](asIScriptContext* ctx) { ctx->SetArgDWord(0, idKart); }); } // onTriggerItemApproached diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 2f9285918..8a7bb01f3 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -270,7 +270,7 @@ public: TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationSound(); - virtual void onTriggerItemApproached(Item* who) OVERRIDE; + virtual void onTriggerItemApproached() OVERRIDE; virtual void update(float dt) OVERRIDE; virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE; @@ -378,7 +378,7 @@ public: virtual ~TrackObjectPresentationActionTrigger() {} - virtual void onTriggerItemApproached(Item* who) OVERRIDE; + virtual void onTriggerItemApproached() OVERRIDE; // ------------------------------------------------------------------------ /** Reset the trigger (i.e. sets it to active again). */ virtual void reset() OVERRIDE { m_action_active = true; }