diff --git a/rwengine/include/script/ScriptTypes.hpp b/rwengine/include/script/ScriptTypes.hpp index 78232e68..b48e31da 100644 --- a/rwengine/include/script/ScriptTypes.hpp +++ b/rwengine/include/script/ScriptTypes.hpp @@ -55,6 +55,18 @@ struct SCMOpcodeParameter { }; template T* handleOf() const { return static_cast(*handle); } + + int integerValue() const + { + if ( type == TGlobal ) + { + return * globalInteger; + } + else + { + return integer; + } + } }; typedef std::vector SCMParams; diff --git a/rwengine/src/script/ScriptMachine.cpp b/rwengine/src/script/ScriptMachine.cpp index 3f5c879b..34938f7e 100644 --- a/rwengine/src/script/ScriptMachine.cpp +++ b/rwengine/src/script/ScriptMachine.cpp @@ -29,6 +29,21 @@ bool SCMOpcodes::findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out) void ScriptMachine::executeThread(SCMThread &t, int msPassed) { +#if SCM_DEBUG_INSTRUCTIONS + std::string threadfilter; + if(getenv("SCM_DEBUG_THREAD")) + { + threadfilter = getenv("SCM_DEBUG_THREAD"); + } + + bool debug_op = threadfilter.empty() || threadfilter.find(t.name) != std::string::npos || threadfilter.find(std::to_string(t.baseAddress)) != std::string::npos; + + if ( debug_op ) + { + std::cout << t.name << " " << t.wakeCounter << std::endl; + } +#endif + if( t.wakeCounter > 0 ) { t.wakeCounter = std::max( t.wakeCounter - msPassed, 0 ); } @@ -145,13 +160,6 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed) else { #if SCM_DEBUG_INSTRUCTIONS - std::string threadfilter; - if(getenv("SCM_DEBUG_THREAD")) - { - threadfilter = getenv("SCM_DEBUG_THREAD"); - } - - bool debug_op = threadfilter.empty() || threadfilter.find(t.name) != std::string::npos || threadfilter.find(std::to_string(t.baseAddress)) != std::string::npos; if( debug_op ) { std::cout << std::setw(7) << std::setfill(' ') << t.name << diff --git a/rwengine/src/script/modules/ObjectModule.cpp b/rwengine/src/script/modules/ObjectModule.cpp index c8f22beb..e3b40171 100644 --- a/rwengine/src/script/modules/ObjectModule.cpp +++ b/rwengine/src/script/modules/ObjectModule.cpp @@ -252,6 +252,28 @@ bool game_player_in_area_2d_in_vehicle(const ScriptArguments& args) return false; } +bool game_character_near_point_on_foot_3D(const ScriptArguments& args) +{ + auto controller = static_cast(*args[0].handle); + glm::vec3 center(args[1].real, args[2].real, args[3].real); + glm::vec3 size(args[4].real, args[5].real, args[6].real); + bool drawCylinder = !!args[7].integer; + + auto vehicle = controller->getCharacter()->getCurrentVehicle(); + if( ! vehicle ) { + auto distance = center - controller->getCharacter()->getPosition(); + distance /= size; + if( glm::length( distance ) < 1.f ) return true; + } + + if( drawCylinder ) + { + args.getVM()->getWorld()->drawAreaIndicator(AreaIndicatorInfo::Cylinder, center, size); + } + + return false; +} + bool game_character_near_point_in_vehicle(const ScriptArguments& args) { auto controller = static_cast(*args[0].handle); @@ -961,6 +983,7 @@ ObjectModule::ObjectModule() bindFunction(0x00ED, game_character_near_point_on_foot_2D, 6, "Is Character near point on foot" ); bindUnimplemented( 0x00F5, game_locate_character_in_sphere, 8, "Locate Player In Sphere" ); + bindFunction(0x00F6, game_character_near_point_on_foot_3D, 8, "Is Character near point on foot" ); bindFunction(0x0100, game_character_near_point_in_vehicle, 8, "Is Character near point in car" ); diff --git a/rwengine/src/script/modules/VMModule.cpp b/rwengine/src/script/modules/VMModule.cpp index 47f6dc6e..5f36faf6 100644 --- a/rwengine/src/script/modules/VMModule.cpp +++ b/rwengine/src/script/modules/VMModule.cpp @@ -11,7 +11,7 @@ SCMThread::pc_t localizeLabel(SCMThread* t, int label) void vm_sleep(const ScriptArguments& args) { - args.getThread()->wakeCounter = args[0].integer; + args.getThread()->wakeCounter = args[0].integerValue(); if( args.getThread()->wakeCounter == 0 ) { args.getThread()->wakeCounter = -1; }