This is how I've been sending clicks. The next step would be to have the waypoints in it's own file, but you get the idea. See my previous posts for more details about every/after because C_Timer functions will likely be in a different address space than your custom functions (Access Violation).
Code:
local arriveDist = 10
local clicked = false
function posToVector2()
local x, y, z = getPosition()
return {x = x, y = y}
end
function distance(x1, y1, x2, y2)
local dx = x1 - x2
local dy = y1 - y2
return math.sqrt(dx * dx + dy * dy)
end
function checkDistance(dest)
local pos = posToVector2(getPosition())
return distance(dest.x, dest.y, pos.x, pos.y) < arriveDist
end
local i = 1
local dests = {{x = -8951, y -905}, {x = -8979, y = -888}, {x = -9005, y = -883}}
function moveNext()
print(checkDistance(dests[i]))
if not clicked then
clicked = true
ctm(dests[i].x, dests[i].y, 0)
elseif checkDistance(dests[i]) then
i = i + 1
clicked = false
end
end
every(500, 'moveNext')
Register Handler
Code:
void LuaScript::RegisterHandler(string commandName, GameMethods::LuaCallback callback)
{
GameMethods::Register(commandName.c_str(), LuaScript::WriteCallback(callback));
}
// not ideal but works
GameMethods::LuaCallback LuaScript::WriteCallback(GameMethods::LuaCallback callback)
{
static auto runOnce = true;
if (!runOnce)
return callback;
runOnce = false;
uintptr_t invalidPtrCheckMax = Offsets::Base + Offsets::InvalidPtrCheckMax;
uintptr_t invalidPtrCheckMin = Offsets::Base + Offsets::InvalidPtrCheckMin;
*reinterpret_cast<uintptr_t*>(invalidPtrCheckMax) = uintptr_t(callback) + 0x1000; // doesn't have to be 1000 just enough space
*reinterpret_cast<uintptr_t*>(invalidPtrCheckMin) = 2;
return callback;
}
Click To Move
Code:
int LuaScript::ClickToMove(int64_t luaState)
{
if (!Player)
return 1;
int x = GameMethods::ToNumber(luaState, 1);
int y = GameMethods::ToNumber(luaState, 2);
int z = GameMethods::ToNumber(luaState, 3);
Vector3 position = Vector3(x, y, z);
GameMethods::ClickToMove(Player->Ptr(), position);
SetHardwareEvent();
return 1;
}
After and Every (tick After)
Code:
int LuaScript::ExecuteAfterMS(int64_t luaState)
{
auto delay = GameMethods::ToNumber(luaState, 1);
auto function = GameMethods::ToLString(luaState, 2, nullptr) + "()";
if (delay <= 0)
return 1;
LuaBase::Input(function, delay);
return 1;
}
int LuaScript::ExecuteEveryMS(int64_t luaState)
{
auto sleepTime = GameMethods::ToNumber(luaState, 1);
auto function = GameMethods::ToLString(luaState, 2, nullptr);
string functionRepeater = "function " + function + "Repeater() " + function + "() after(" + to_string(sleepTime) + ", '" + function + "Repeater') end " + function + "Repeater()";
LuaBase::Input(functionRepeater, 0);
return 1;
}
Get Position
Code:
int LuaScript::GetPlayerPosition(int64_t luaState)
{
SetPlayer();
GameMethods::PushNumber(luaState, Player->GetUnitPosition(0, 0).X);
GameMethods::PushNumber(luaState, Player->GetUnitPosition(0, 0).Y);
GameMethods::PushNumber(luaState, Player->GetUnitPosition(0, 0).Z);
return 3;
}