Arguments passed into function display, but error out as nil

Discuss, ask for help, share ideas, give suggestions, read tutorials, and tell us about bugs you have found with MicroMacro in here.

Do not post RoM-Bot stuff here. There is a subforum for that.
Forum rules
This is a sub-forum for things specific to MicroMacro.

This is not the place to ask questions about the RoM bot, which uses MicroMacro. There is a difference.
Post Reply
Message
Author
Sgraffite
Posts: 38
Joined: Wed Jul 09, 2008 12:03 pm

Arguments passed into function display, but error out as nil

#1 Post by Sgraffite » Sat Nov 08, 2008 12:22 am

I could really use some help here as I don't understand what is wrong. I'm trying to implement zerosignal's waypoint navigation system into a custom script (thanks zerosignal!). Basically I'm passing a table from class function A to function B outside of any classes. At the very beginning of function B, I printf the args, and they show up, but then I get an error on the same line that printed them, saying they are nil. How can it display them if they are nil?

I've been hitting this brick wall for 5+ hours now, making no progress. I rewrote everything as procederal, and ran into the exact same problem. I removed things trying to narrow down the problem, but I always end up at the same place, not being able to use the args I pass in to the function, because it thinks they are nil, even though it can display them. I tried simplifying the problem so I would not need to post all of the code, to no avail. My best guess is that it is erroring out somewhere other than where it says, but really I have no idea at this point. Please help!

Here is the code:

test_main.lua

Code: Select all

include( "test_char.lua" );
include( "test_funcs.lua" );

startKey = key.VK_INSERT;
stopKey = key.VK_DELETE;

function main()
    proc = openProcess(findProcessByExe("game.exe"));
    win = findWindow("Shaiya");
    attach(win);
    setPriority(PRIORITY_HIGH);

    waypoints = {};
    waypoints[0] = { x=1262,z=755};
    
    --instantiate new character class
    local myChar = class(Character);
    myChar:initialize(proc);
    
    registerTimer("updater", 200, function() myChar:update() end );
    myChar:move_to(waypoints[0]);
    --while( true ) do
        yrest(500);
        --myChar:update();
    --end
end

startMacro(main);
test_char.lua

Code: Select all

-- constructor.
-- @param obj The Character object.
-- @param options The character options, they will overwrite any default values.
Character = class();

function Character:initialize(proc)
    self.status = USER_IDLE;
    self.last_target_id = 0
    self.cur_target_id = 0
    self.cur_target_health = 0
    self.cur_target_last_health = 0
    self.hp = 0
    self.hp_max = 0
    self.sp = 0
    self.sp_max = 0
    self.mp = 0
    self.mp_max = 0
    self.x = 0
    self.y = 0
    self.z = 0
    self.rot_x = 0
    self.rot_y = 0
    self.pickup_count = 0
    
    self.proc = proc
    
    character_ptr = 0x081CBEC;
    hp_max_offset = 304;
    mp_max_offset = 312;
    sp_max_offset = 320;
    self.hp_max = memoryReadIntPtr(self.proc, character_ptr, hp_max_offset);
    self.mp_max = memoryReadIntPtr(self.proc, character_ptr, mp_max_offset);
    self.sp_max = memoryReadIntPtr(self.proc, character_ptr, sp_max_offset);
    printf("self hpmax="..self.hp_max.."\n");
    
    self:update();
end

function Character:update()
    character_ptr = 0x081CBEC;
    hp_offset = 300;
    mp_offset = 308;
    sp_offset = 316;
    
    pos_x = 16;
    pos_y = 20;
    pos_z = 24;
    pos_rot_x = 28;
    pos_rot_y = 36;
    
    targetid_addr = 0x006C7BC4; -- short, 65535 if none selected
    
    self.hp = memoryReadIntPtr(self.proc, character_ptr, hp_offset);
    self.mp = memoryReadIntPtr(self.proc, character_ptr, mp_offset);
    self.sp = memoryReadIntPtr(self.proc, character_ptr, sp_offset);
    
    self.x = memoryReadFloatPtr(self.proc, character_ptr, pos_x);
    self.y = memoryReadFloatPtr(self.proc, character_ptr, pos_y);
    self.z = memoryReadFloatPtr(self.proc, character_ptr, pos_z);
    self.rot_x = memoryReadFloatPtr(self.proc, character_ptr, pos_rot_x);
    self.rot_y = memoryReadFloatPtr(self.proc, character_ptr, pos_rot_y);
end

function Character:move_to(pos)
    local l_check_interval = 250;
    --debug_message("pos (" .. math.floor(self.x) .. "," .. math.floor(self.z) .. ")")
    --debug_message("move_to (" .. pos.x .. "," .. pos.z .. ")")
    local tempx = pos.x - self.x;
    local tempy = pos.z - self.z;
    local l_pos_relative = { x=tempx,y=tempy};
    
    local l_deg = get_quadrantal_angle(l_pos_relative);
    self:rotate_to(l_deg);
    local l_tolerance = 4;

    local l_pos_new = {
        min_x=(pos.x - l_tolerance),
        max_x=(pos.x + l_tolerance),
        min_z=(pos.z - l_tolerance),
        max_z=(pos.z + l_tolerance),
    }

    --keyboardHold(key_move[DIRECTION_UP])
    while (true) do
        self.pos = {x=self.x,z=self.z};
        if (self.x >= l_pos_new.min_x and 
            self.x <= l_pos_new.max_x and
            self.z >= l_pos_new.min_z and 
            self.z <= l_pos_new.max_z)then
                break;
        end
        --self:move(DIRECTION_UP, 10)
        coroutine.yield()
    end
    --keyboardRelease(key_move[DIRECTION_UP])
    --debug_message("moved_to (" .. math.floor(self.x) .. "," .. math.floor(self.z) .. ")")
end

function Character:rotate_to(degrees)
    --local l_pos_cur = self:get_rotation(l_pos)
    local l_deg_cur = get_quadrantal_angle(self.rotation)
    --debug_message("deg_cur: " .. l_deg_cur)
    --debug_message("deg_new: " .. degrees)
    local l_increment = 0.75
    local l_pos_new = {
        x=math.cos(math.rad(degrees)),
        y=math.sin(math.rad(degrees)),
    }
    --debug_message("l_x: " .. l_pos_new.x .. ", " .. "l_y: " .. l_pos_new.y)

    local l_tolerance = math.rad(l_increment)
    local l_direction = get_rotate_direction(l_deg_cur, degrees)
    l_pos_new.min_x = l_pos_new.x - l_tolerance
    l_pos_new.max_x = l_pos_new.x + l_tolerance
    l_pos_new.min_y = l_pos_new.y - l_tolerance
    l_pos_new.max_y = l_pos_new.y + l_tolerance

    while (true) do
        self.rotation = self:get_avi_rotation()
        self:spin(l_direction, l_increment)
        --l_pos_cur = self:get_rotation(l_pos)
        
        --debug_message("l_cx: " .. l_pos_cur.x .. ", " .. "l_cy: " .. l_pos_cur.y)
        if (self.rotation.x >= l_pos_new.min_x and 
            self.rotation.x <= l_pos_new.max_x and
            self.rotation.y >= l_pos_new.min_y and 
            self.rotation.y <= l_pos_new.max_y)then
                break;
        end
        coroutine.yield()
    end
end

function Character:get_avi_rotation()
    local l_pos = {
        x=memoryReadFloatPtr(self.proc, character_ptr, pos_rot_x),
        y=memoryReadFloatPtr(self.proc, character_ptr, pos_rot_y),
    }
    return l_pos
end

function Character:spin(direction, angle)
    DIRECTION_UP    = 1
    DIRECTION_RIGHT = 2
    DIRECTION_DOWN  = 3
    DIRECTION_LEFT  = 4
    local l_key = nil;
    if (direction == DIRECTION_RIGHT) then
        l_key = key.VK_A;
    elseif (direction == DIRECTION_LEFT) then
        l_key = key.VK_D;
    end
    AVATAR_ROTATE_SPEED_DELAY = 12;
    keyboardHold(l_key);
    rest(AVATAR_ROTATE_SPEED_DELAY * angle);
    keyboardRelease(l_key);
end
test_funcs.lua

Code: Select all

function distance_2d_point(point_a, point_b)
    local l_d = {
        x=(point_a.x - point_b.x),
        z=(point_a.z - point_b.z),
    }
    --debug_message(sprintf("l_d: %f, %f, %f", l_d.x, l_d.y, l_d.z));
    return ((l_d.x^2) + (l_d.z^2)) ^ 0.5;
end

function get_quadrantal_angle(pos)
    printf("POS IN FUNCTION x="..pos.x.."\n");
    printf("POS IN FUNCTION y="..pos.y.."\n");
    -- find out the opposite angle of the right sided triangle.
    local l_deg_cur = 90 - (math.deg(math.atan(pos.x / pos.y)));
    --debug_message("l_deg_cur: " .. l_deg_cur)
    -- If it's in the 3rd or 4th Quadrant then add 180 degrees.
    if (get_quadrant(pos) >= 3) then
        l_deg_cur = (l_deg_cur + 180) % 360
    end
    --return round(l_deg_cur, 1) % 360
    return l_deg_cur 
end

function get_quadrant(pos)
    if (pos.x >= 0) then 
        if (pos.y >= 0) then
            return 1
        else
            return 4
        end
    else
        if (pos.y >= 0) then
            return 2
        else
            return 3
        end
    end
end

--[[
  Get the closest rotation direction.
  @param degree The current degrees that object is facing (0-360).
  @param degree_new The new degree that object wants to face (0-360).
  @return Rotation direction, DIRECTION_RIGHT for ClockWise (CW), DIRECTION_LEFT for CCW.
]]--
function get_rotate_direction(degree, degree_new)
    l_d_rad = math.rad(degree);
    l_d_new_rad = math.rad(degree_new);
    local l_diff = math.atan2(math.sin(l_d_new_rad-l_d_rad),math.cos(l_d_new_rad-l_d_rad));
    --debug_message("l_diff="..l_diff)
    if (l_diff >= 0) then
        return key.VK_D; --strafe key???
    else
        return key.VK_A; --strafe key???
    end
end

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Arguments passed into function display, but error out as nil

#2 Post by Administrator » Sat Nov 08, 2008 2:58 am

Yes, what you see is a bit misleading. It is, in fact, nil. The information that is printed is from the first call, whereas the second call to that function is resulting in an error. More specifically, the second call to this function is coming from here: function Character:rotate_to(degrees). In your call to get_quadrantal_angle(), self.rotation is nil.

Sgraffite
Posts: 38
Joined: Wed Jul 09, 2008 12:03 pm

Re: Arguments passed into function display, but error out as nil

#3 Post by Sgraffite » Sat Nov 08, 2008 3:50 am

Thanks! I don't want to have others debug code for me, I swear!

zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

Re: Arguments passed into function display, but error out as nil

#4 Post by zer0 » Sun Nov 09, 2008 9:24 am

I'm glad that the code is going to good use, I tried to make them fairly general so they can be applied to other games that have keyboard based movement.

Check out the ZS Shaiya version 0-03b, the move_to, rotate_to functions were improved somewhat (now in avatar_actions.lua), so it corrects itself every small amount of distance. It's working very nice, even casting Sprint on the avatar did not affect the waypoint system. Now I can have waypoints really far without being worried about the avatar missing it, due to being off less than a degree. ^^

I'll get the waypoint application out in a few days, just gotta tie some loose ends.

Sgraffite
Posts: 38
Joined: Wed Jul 09, 2008 12:03 pm

Re: Arguments passed into function display, but error out as nil

#5 Post by Sgraffite » Sun Nov 09, 2008 3:52 pm

It's been a HUGE help! I'm using it to prevent people taking my spot, prevent ks'ing to a degree, as well as safety, and reliability of killing mobs in a specific rotational order.

Basically I set up a circular path of waypoints, and kill the mobs in the exact same order every time. It is timed so that as I run towards a waypoint the mob spawns in, so there's only at most a few seconds of a window for someone else to attack it. It keeps the whole camp dead except the mob I'm currently attacking/about to attack.

I'm on map 4 so there's not much room for error, if two mobs get on me I can die pretty quickly, so this way it is much safer as I only have to fight one at a time.

I'll definitely check the the revised functions, thanks again :)

zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

Re: Arguments passed into function display, but error out as nil

#6 Post by zer0 » Mon Nov 10, 2008 2:29 am

Here is the Waypoint Editor I created if ur interested.
http://solarimpact.servegame.com/phpBB3 ... f=10&t=156

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests